我有以下类。
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
,决定上运行时)
我该怎么做呢?
您可以使用泛型声明
Class<? extends A> klass;
然后你会被允许写
A a = klass.newInstance();
但是,由于Class.forName
对你的类没有类型的信息,并且没有类型推断声明,你会得到“未投”的警告。 这种方法是没有不仅仅是向下转换第二行的结果,更多的类型安全A
。
我想将对象铸造成子类(B或C,决定上运行时)
这是没有意义的。 铸造是一些东西,主要是一个编译时的操作,用适当的类型的表达式来结束。 它然后在执行时验证。
如果你真的想实现类型的变量A
,那么你只需要投给A
:
A a = (A) klass.newInstance();
具有klass
类型的对象Class<T>
可以调用Class.cast()
方法投射到键入T
使用
klass.cast(object)
例如,你有a
类型的B
,你投a
键入B
在运行时加载。
Class<?> klass = Class.forName("B");
klass.cast(a);
要在评论跟进,您可以创建与类的实例或者
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);
当然,你需要相扶适当的例外。