7

我有一个用 type 泛型的类<T extends Enum<T> & Runnable>。我有一个Class<T> bar由类名设置的成员变量:t = (Class<T>) Class.forName(name). 这给了我一个未经检查的演员警告。

通常,使用asSubclass可以在类似的情况下使用,但由于T有多个界限,我无法在没有得到编译器警告的情况下使用它:

//This is type safe, but I still get an unchecked cast warning
t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);

我可以在不使用的情况下以任何方式摆脱这个警告@SupressedWarning("unchecked")吗?

完整示例:

public class Example<T extends Enum<T> & Runnable> {
    Class<T> t;

    Example(String className) throws ClassNotFoundException {
        t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);
    }
}
4

2 回答 2

4
//This is type safe, but I still get an unchecked cast warning
t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);

哇,慢一点!这是真的吗?不,这不对!您所做的只是确定与传入名称匹配的类既是 aRunnable又是 an Enum,而不是实际上是T。您只验证了界限。想象一下我们有课T1并且T2

package foo;
public enum T1 implements Runnable {
    ;
    @Override
    public void run() {
    }
}

package foo;
public enum T2 implements Runnable {
    ;
    @Override
    public void run() {
    }
}

然后这工作正常,但显然不是类型安全的:

Example<T1> example = new Example<T1>("foo.T2");
Class<T1> t1Clazz = example.t; //uh oh...

这也不是多重界限的问题。只有一个界限,你会遇到同样的问题。

Class<T>正如@sp00m 所提到的,真正的解决方案可能是在这里传递。

编辑

另一方面,如果T仅在内部需要(即指定多个边界)并且实际上不需要公开,那么另一种选择是将类维护在两个单独的引用中。例如:

Class<? extends Runnable> runnableClass;
Class<? extends Enum> enumClass;

Example(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    Class<?> clazz = Class.forName(className);
    runnableClass = clazz.asSubclass(Runnable.class);
    enumClass = clazz.asSubclass(Enum.class);
}

这是因为,如果没有类型参数,很少有情况可以实际利用它同时是 anenum和 a的知识Runnable。如果创建类的实例,则需要将其分配给类型为Runnable或的变量/字段Enum;你不能两者都做。

于 2013-07-09T21:53:27.980 回答
1

我相信你根本不能......我认为最好的解决方案是Class<T> clazz直接传递 as 参数而不是它的String name.

于 2013-07-09T09:17:54.500 回答