Ale*_*øld 7 java generics casting
我有一个类型的格式<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);
Run Code Online (Sandbox Code Playgroud)
我可以不用任何方式摆脱这个警告@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);
}
}
Run Code Online (Sandbox Code Playgroud)
//This is type safe, but I still get an unchecked cast warning
t = (Class<T>) Class.forName(className).asSubclass(Enum.class).asSubclass(Runnable.class);
Run Code Online (Sandbox Code Playgroud)
哇,慢一点!这真的是真的吗?不,这不对!您所做的只是确定与传入名称匹配的类既是 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() {
}
}
Run Code Online (Sandbox Code Playgroud)
那么这工作正常,但显然不是类型安全的:
Example<T1> example = new Example<T1>("foo.T2");
Class<T1> t1Clazz = example.t; //uh oh...
Run Code Online (Sandbox Code Playgroud)
这也不是多重界限的问题。如果只有一个边界,你也会遇到同样的问题。
正如@sp00m提到的,真正的解决方案可能是在Class<T>这里传递。
另一方面,如果仅在内部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);
}
Run Code Online (Sandbox Code Playgroud)
这是因为,如果没有类型参数,那么在极少数情况下您实际上可以同时利用enum它是 an和 a 的知识。Runnable如果创建类的实例,则需要将其分配给类型为Runnable或的变量/字段Enum;你不能两者兼得。