Java 如何将通配符(?)强制转换为泛型类型T?

Java 如何将通配符(?)强制转换为泛型类型T?,java,generics,casting,wildcard,Java,Generics,Casting,Wildcard,我有一个静态方法,我想用它在运行时加载类并实例化我的对象,但当我编译时,我得到了以下警告: warning: [unchecked] unchecked cast T t = (T) ctor.newInstance(); required: T found: CAP#1 where T is a type-variable: T extends Object declared in method <T>forName(String,Set<

我有一个静态方法,我想用它在运行时加载类并实例化我的对象,但当我编译时,我得到了以下警告:

warning: [unchecked] unchecked cast
            T t = (T) ctor.newInstance();
required: T
found:    CAP#1
where T is a type-variable:
    T extends Object declared in method <T>forName(String,Set<String>)
    where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 warning
警告:[未选中]未选中强制转换
T=(T)ctor.newInstance();
必填项:T
发现:第1章
其中T是一个类型变量:
T扩展方法forName(字符串,集合)中声明的对象
其中CAP#1是一个新类型变量:
CAP#1将对象从捕获扩展到?
1警告
代码如下:

public static <T> Set<T> forName(String modulePath, Set<String> classes) throws InvalidModuleException{
    try {
        ClassLoader cl = new URLClassLoader(new URL[]{new URL(modulePath)});

        Set<T> list = new HashSet<>(classes.size());
        for (String className : classes) {
            Class<?> clazz = (Class<?>) Class.forName(className, true, cl);
            Constructor<?> ctor = clazz.getConstructor();
            T t = (T) ctor.newInstance();
            list.add(t);
        }
        return list;    
    } catch (MalformedURLException | ReflectiveOperationException ex) {
        throw new InvalidModuleException(ex.getMessage());
    }
}
publicstaticsetforname(stringmodulepath,setclasses)抛出InvalidModuleException{
试一试{
ClassLoader cl=newurlclassloader(newurl[]{newurl(modulePath)});
Set list=newhashset(classes.size());
for(字符串类名称:类){
Class clazz=(Class)Class.forName(className,true,cl);
Constructor=clazz.getConstructor();
T=(T)ctor.newInstance();
列表。添加(t);
}
退货清单;
}catch(格式错误的异常| ReflectiveOperationException ex){
抛出新的InvalidModuleException(例如getMessage());
}
}
有人能给我解释一下吗

[更新] 下面是方法调用的示例:

HashSet<String> set = new HashSet<>();
h.add("fully_classfied_classname_readed_from_file"); //Class that extends AbstractApplication
Set<AbstractApplication> abs = Apps.forName("plugins/module.jar", set);
HashSet=newhashset();
h、 添加(“完全分类的”类名“从”文件中读取”)//扩展抽象应用程序的类
Set abs=Apps.forName(“plugins/module.jar”,Set);

使用字符串来指示类,不能以安全的方式执行此操作。首先,编译器无法知道字符串集实际上包含完全限定的类名;即使它们是类名,也不能保证由名称指定的类是
T
的子类

不是传入一组字符串,而是传入一组类,这些类被约束为
T
的子类:

Set<Class<? extends T>> classes

Set缺少一位。首先,您尝试将每个对象类型转换为
T
。如果您知道
T
prehand,我看不出在类对象需要传递一组字符串时需要传递给谁的原因

假设在可能存在子类的情况下,您仍然需要:

public static <T> Set<? extends T> forName(String modulePath, Set<String> classes, Class<T> claz) throws InvalidModuleException{
    try {
    ClassLoader cl = new URLClassLoader(new URL[]{new URL(modulePath)});

    Set<T> list = new HashSet<>(classes.size());
    for (String className : classes) {
        Class<?> clazz = Class.forName(className, true, cl);
        Constructor<?> ctor = clazz.getConstructor();
        Object obj = ctor.newInstance();
        list.add(claz.cast(obj));
    }
    return list;
} catch (MalformedURLException | ReflectiveOperationException | ClassCastException ex) {
    throw new InvalidModuleException(ex.getMessage());
}
}
public static Set clazz=Class.forName(className,true,cl);
Constructor=clazz.getConstructor();
Object obj=ctor.newInstance();
列表添加(类别铸件(obj));
}
退货清单;
}catch(格式错误的异常| ReflectiveOperationException | ClassCastException ex){
抛出新的InvalidModuleException(例如getMessage());
}
}

我使用集合,因为类名是从文件读取的。我将要使用的类保存在一个文件中。@ehbarbian请参考最后一句话。从类型的角度来看,你做的事情本质上是不安全的。这就是我想要的。加载子类(请参阅更新)。我想你的代码会有帮助。或者,你可以事先更改类的类型
public static <T> Set<? extends T> forName(String modulePath, Set<String> classes, Class<T> claz) throws InvalidModuleException{
    try {
    ClassLoader cl = new URLClassLoader(new URL[]{new URL(modulePath)});

    Set<T> list = new HashSet<>(classes.size());
    for (String className : classes) {
        Class<?> clazz = Class.forName(className, true, cl);
        Constructor<?> ctor = clazz.getConstructor();
        Object obj = ctor.newInstance();
        list.add(claz.cast(obj));
    }
    return list;
} catch (MalformedURLException | ReflectiveOperationException | ClassCastException ex) {
    throw new InvalidModuleException(ex.getMessage());
}
}