我有以下课程。
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
我希望将对象转换为子类(B
或C
,在运行时决定)
我该怎么做?
答案 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();
或者,如果方法采用参数(例如int
和String
)
int param1 = ...;
String param2 = ...;
klass.getMethod(a, new Class[] { Integer.class, String.class }).invoke(param1, param2);
当然,您需要捕捉适当的例外情况。