Class someInterface = Class.fromName("some.package.SomeInterface");
Làm cách nào để tạo lớp mới triển khai someInterface
?Phản ánh Java: Tạo lớp triển khai
Tôi cần tạo lớp mới và chuyển lớp đó đến hàm cần số SomeInterface
làm đối số.
Class someInterface = Class.fromName("some.package.SomeInterface");
Làm cách nào để tạo lớp mới triển khai someInterface
?Phản ánh Java: Tạo lớp triển khai
Tôi cần tạo lớp mới và chuyển lớp đó đến hàm cần số SomeInterface
làm đối số.
Tạo nội dung giả vờ để triển khai giao diện trên thực tế không quá khó. Bạn có thể sử dụng java.lang.reflect.Proxy
sau khi triển khai InvocationHandler
để xử lý mọi cuộc gọi phương thức.
Tất nhiên, bạn thực sự có thể tạo một lớp học thực với thư viện như BCEL.
Nếu mục đích này là dành cho mục đích thử nghiệm, bạn nên xem các khuôn khổ nhạo báng như jMock và EasyMock.
Whoa, gọn gàng! Tôi tự hỏi những gì khác là trong gói java.lang.reflect mà tôi không biết? –
Nếu bạn muốn vượt ra ngoài giao diện, bạn có thể muốn xem cglib và objenesis. Cùng nhau, họ sẽ cho phép bạn làm một số công cụ khá mạnh mẽ, mở rộng một lớp trừu tượng và khởi tạo nó. (Ví dụ: jMock sử dụng chúng cho mục đích đó.)
Nếu bạn muốn gắn bó với giao diện, hãy làm những gì Jon Skeet đã nói :).
Thực ra, bạn phải sử dụng tên lớp trong phương thức Class.fromName() và truyền đến loại giao diện của bạn. Xem mẫu dưới đây có giúp ích không.
public class Main {
public static void main(String[] args) throws Exception {
Car ferrari = (Car) Class.forName("Mercedez").newInstance();
System.out.println(ferrari.getName());
}
}
interface Car {
String getName();
}
class Mercedez implements Car {
@Override
public String getName() {
return "Mercedez";
}
}
class Ferrari implements Car {
@Override
public String getName() {
return "Ferrari";
}
}
Điều này bỏ lỡ điểm của câu hỏi. Câu hỏi của OP là một chút không rõ ràng, nhưng họ đang tìm kiếm một cách để thực hiện một lớp học trong thời gian chạy. Không chỉ đơn giản là tạo ra một đối tượng của một lớp học chưa biết nhưng có hiệu quả tạo ra một lớp mới hoàn toàn. –
nó thậm chí không gần với chủ đề –
Dễ dàng, java.lang.reflect.Proxy
để giải cứu!
Full dụ làm việc:
interface IRobot {
String Name();
String Name(String title);
void Talk();
void Talk(String stuff);
void Talk(int stuff);
void Talk(String stuff, int more_stuff);
void Talk(int stuff, int more_stuff);
void Talk(int stuff, String more_stuff);
}
public class ProxyTest {
public static void main(String args[]) {
IRobot robot = (IRobot) java.lang.reflect.Proxy.newProxyInstance(
IRobot.class.getClassLoader(),
new java.lang.Class[] { IRobot.class },
new java.lang.reflect.InvocationHandler() {
@Override
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
String method_name = method.getName();
Class<?>[] classes = method.getParameterTypes();
if (method_name.equals("Name")) {
if (args == null) {
return "Mr IRobot";
} else {
return args[0] + " IRobot";
}
} else if (method_name.equals("Talk")) {
switch (classes.length) {
case 0:
System.out.println("Hello");
break;
case 1:
if (classes[0] == int.class) {
System.out.println("Hi. Int: " + args[0]);
} else {
System.out.println("Hi. String: " + args[0]);
}
break;
case 2:
if (classes[0] == String.class) {
System.out.println("Hi. String: " + args[0] + ". Int: " + args[1]);
} else {
if (classes[1] == String.class) {
System.out.println("Hi. int: " + args[0] + ". String: " + args[1]);
} else {
System.out.println("Hi. int: " + args[0] + ". Int: " + args[1]);
}
}
break;
}
}
return null;
}
});
System.out.println(robot.Name());
System.out.println(robot.Name("Dr"));
robot.Talk();
robot.Talk("stuff");
robot.Talk(100);
robot.Talk("stuff", 200);
robot.Talk(300, 400);
robot.Talk(500, "stuff");
}
}
Đây là một bài bổ sung tốt cho câu trả lời này: http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html – jonashackt
smoove .. thanks. – kwikness
Tạo lớp một cách nhanh chóng là không dễ dàng chút nào, tôi sợ. –
@MichaelMyers Cũng không khó như vậy, http://stackoverflow.com/a/9583681/632951 – Pacerier