Java 反射:创建一个实现类
Posted
技术标签:
【中文标题】Java 反射:创建一个实现类【英文标题】:Java Reflection: Create an implementing class 【发布时间】:2010-11-08 03:29:03 【问题描述】:Class someInterface = Class.fromName("some.package.SomeInterface");
我现在如何创建一个实现someInterface
的新类?
我需要创建一个新类,并将其传递给需要SomeInterface
作为参数的函数。
【问题讨论】:
动态创建课程并不容易,恐怕。 @MichaelMyers 也没有那么难,***.com/a/9583681/632951 【参考方案1】:很容易,java.lang.reflect.Proxy
来救援!
完整的工作示例:
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");
【讨论】:
这是对该答案的一个很好的附加帖子:tutorials.jenkov.com/java-reflection/dynamic-proxies.html【参考方案2】:创建一个假装在运行中实现接口的东西实际上并不太难。在实现InvocationHandler
之后,您可以使用java.lang.reflect.Proxy
来处理任何方法调用。
当然,您实际上可以使用 BCEL 之类的库生成一个真实的类。
如果这是出于测试目的,您应该查看像 jMock 和 EasyMock 这样的模拟框架。
【讨论】:
哇,太棒了!我想知道 java.lang.reflect 包中还有什么我不知道的?【参考方案3】:如果你想超越接口,你可能想看看cglib 和objenesis。它们一起将允许你做一些非常强大的事情,扩展一个抽象类并实例化它。 (例如,jMock 将它们用于此目的。)
如果您想坚持使用接口,请按照 Jon Skeet 所说的做 :)。
【讨论】:
【参考方案4】:实际上,您必须在 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";
【讨论】:
这没有抓住问题的关键。 OP 的问题有点不清楚,但他们正在寻找一种在运行时实现类的方法。不仅仅是创建一个未知类的对象,而是完全有效地创建一个新类。 离主题还差得很远以上是关于Java 反射:创建一个实现类的主要内容,如果未能解决你的问题,请参考以下文章