java - 泛型和 Class.forName

标签 java generics instantiation

我想使用其名称创建指定类的实例。我的代码如下所示。

我收到编译器警告。我这样做对吗?甚至可以使用类的名称并获取该类型的实例,因为我认为编译器无法知道该类型应该是什么?

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();
    }
}

谢谢

最佳答案

我认为第一种方法应该是这样的:

public static <T> T create(final String className, Class<T> ifaceClass) 
throws ClassNotFoundException {
    final Class<T> clazz = Class.forName(className).asSubclass(ifaceClass);
    return create(clazz); 
}

如果没有那些讨厌的类型安全警告,你不能使用类型参数进行向上类型转换。

顺便说一下,如果你忽略这些警告,create 方法可能会创建一个与调用者使用的实际类型不兼容的类的实例。这很可能会导致稍后出现意外的ClassCastException;例如分配实例时。


编辑:@Pascal 指出我们需要添加一个类型转换来进行编译;即

Class<T> clazz = (Class<T>) Class.forName(className).asSubclass(ifaceClass);

很遗憾,我们需要添加一个@SuppressWarnings注解。

关于java - 泛型和 Class.forName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1733799/

相关文章:

Java:与ArrayList循环相同类型的新实例停止循环

java - springboot org.apache.jasper.JasperException 根据 TLD,标签属性无效

java - 使用 Microsoft 的 JDBC 驱动程序创建连接比使用 jTDS 快 3 倍

c# - 实现缺少新约束的通用接口(interface)

xml - 如何将 ns1.MyPersonalClass 转换为 ns2.MyPersonalClass ?他们拥有相同的属性(property)或成员

oop - 仅实例化一个类的唯一对象

java - 我应该如何格式化 3D 引擎的几何实例化过程?

java - 正则表达式仅从 xml 标签中删除 uri 前缀(标签内)

java - eclipse java 如何将 sqlite-jdbc-(VERSION).jar 放入我的项目并使用它

java - 自 Java5 + 菱形运算符以来初始化通用集合的方法