在java中使用反射来转换类

时间:2013-06-26 13:33:33

标签: java reflection casting

我有以下课程。

abstract class A{}

class B extends A{}

class C extends A{}

我需要创建一个这样的对象

A a = new B();

我在运行时获取子类的类名。所以,我需要使用反射来创建一个对象。

我做到了。

Class<?> klass = Class.forName(className);

现在我无法将此类强制转换为子类。

我想实现

A a = klass.newInstance(); // returns Object

我希望将对象转换为子类(BC,在运行时决定)

我该怎么做?

4 个答案:

答案 0 :(得分:3)

您可以使用Generics声明

Class<? extends A> klass;
然后你就可以写

A a = klass.newInstance();

但是,由于Class.forName没有关于您的类的类型信息,并且没有声明类型推断,因此您将收到“未选中的强制转换”警告。这种方法不仅仅是将第二行的结果向下转换为A

答案 1 :(得分:2)

  

我希望将对象转换为子类(B或C,在运行时决定)

这没有任何意义。转换主要是一种编译时操作,最终得到适当类型的表达式。然后在执行时验证它。

如果您真的想要获得A类型的变量,那么您只需要转换为A

A a = (A) klass.newInstance();

答案 2 :(得分:1)

拥有klass类型的Class<T>对象,您可以使用

调用Class.cast()方法转换为T类型
klass.cast(object)

例如,您有a类型B,您将a转换为在运行时加载的B类型。

Class<?> klass = Class.forName("B");
klass.cast(a);

答案 3 :(得分:0)

要跟进评论,您可以使用

创建课程实例
Class klass = Class.forName(className);
A a = (A)klass.newInstance();

Class<? extends A> klass = Class.forName(className);
A a = klass.newInstance();

然后你可以用:

调用它上面的方法
klass.getMethod(methodName, null).invoke();

或者,如果方法采用参数(例如intString

int param1 = ...;
String param2 = ...;
klass.getMethod(a, new Class[] { Integer.class, String.class }).invoke(param1, param2);

当然,您需要捕捉适当的例外情况。