我想用它的名字创建一个指定类的实例。我的代码如下所示。
我得到一个编译器警告。我这样做是对的吗?有没有可能使用一个类的名称并获取该类型的一个实例,因为我认为编译器没有任何方法知道应该是什么类型?
public static <T> T create(final String className) {
try {
final Class<?> clazz = Class.forName(className);
//WARNING: Type safety: Unchecked cast from capture#2-of ? to T
return (T) create(clazz);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static <T> T create(final Class<T> classToCreate) {
final Constructor<T> constructor;
try {
constructor = classToCreate.getDeclaredConstructor();
final T result = constructor.newInstance();
return result;
}
catch (Exception e) {
e.printStackTrace();
}
}
谢谢
发布于 2009-11-14 17:50:20
我认为这是因为Class.forName(..)
没有为T参数化。当您触发eclipse自动完成时,它假定clazz.newInstance()返回对象。因此,保留强制转换并添加@SuppressWarnings。如果您没有正确使用该方法(即String str = Utils.create("java.util.ArrayList");
),则会发生ClassCastException
,但这是正常的。
发布于 2009-11-14 20:35:51
不能将类型参数限制为包含名为className的类型。因此,调用者可以为create(String)函数提供任何类型,这当然不是类型安全的。
因为您不能静态地强制要求返回的实例实现任何接口(而不是让调用者通过传递相应的Class对象来告诉您),所以我不使用泛型,而是让调用者将其转换为他所期望的任何类型。
public static Object create(final String className) {
try {
final Class<?> clazz = Class.forName(className);
return create(clazz);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
然后,调用者可以这样写:
Foo foo = (Foo) create("my.cool.FooBar");
而不是
Foo foo = create("my.cool.FooBar", Foo.class);
发布于 2009-11-14 19:10:50
即使您可以运行上面的代码,构造函数的newInstance()方法也假定构造函数为零参数构造函数。
如果类没有一个,即你试图创建的类的零参数构造函数已经显式地声明为私有,或者包,这取决于方法的调用位置,你将得到一个IllegalAccessException。在你的前提条件中添加一些东西,如果你让它工作的话。
https://stackoverflow.com/questions/1733799
复制相似问题