Java 反射:创建一个实现类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1082850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Reflection: Create an implementing class
提问by Isaac Waller
Class someInterface = Class.fromName("some.package.SomeInterface");
How do I now create a new class that implements someInterface
?
我现在如何创建一个实现 的新类someInterface
?
I need to create a new class, and pass it to a function that needs a SomeInterface
as an argument.
我需要创建一个新类,并将其传递给需要 aSomeInterface
作为参数的函数。
采纳答案by Jon Skeet
Creating something which pretends to implement an interface on the fly actually isn't too hard. You can use java.lang.reflect.Proxy
after implementing InvocationHandler
to handle any method calls.
创建一些假装即时实现接口的东西实际上并不太难。您可以java.lang.reflect.Proxy
在实现后使用InvocationHandler
来处理任何方法调用。
Of course, you could actually generate a real class with a library like BCEL.
当然,您实际上可以使用像BCEL这样的库生成一个真正的类。
If this is for test purposes, you should look at mocking frameworks like jMockand EasyMock.
回答by jqno
If you want to go beyond interfaces, you might want to take a look at cgliband objenesis. Together, they will allow you to do some pretty powerful stuff, extending an abstract class and instantiating it. (jMockuses them for that purpose, for example.)
如果你想超越接口,你可能想看看cglib和objenesis。在一起,它们将允许您做一些非常强大的事情,扩展抽象类并实例化它。(例如,jMock为此目的使用它们。)
If you want to stick with interfaces, do what Jon Skeet said :).
如果您想坚持使用接口,请按照 Jon Skeet 所说的去做:)。
回答by nandokakimoto
Actually, you have to use the class name in Class.fromName() method and cast to your interface type. See if the sample below helps.
实际上,您必须在 Class.fromName() 方法中使用类名并转换为您的接口类型。看看下面的示例是否有帮助。
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";
}
}
回答by Pacerier
Easily, java.lang.reflect.Proxy
to the rescue!
Full working example:
完整的工作示例:
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");
}
}