在泛型

时间:2016-10-20 00:32:10

标签: java generics

请查看以下代码:

Class<? extends List> class1;
Class<? extends List<?>> class2;
Class<? extends List<? extends Object>> class3;
class1 = class2.asSubclass(List.class);     // 1. OK
class1 = class3.asSubclass(List.class);     // 2. OK
class2 = class1.asSubclass(List.class);     // 3. Error Type Mismatch
class2 = class3.asSubclass(List.class);     // 4. Error Type Mismatch
class3 = class1.asSubclass(List.class);     // 5. Error Type Mismatch
class3 = class2.asSubclass(List.class);     // 6. Error Type Mismatch
String className;
class1 = Class.forName(className);          // 7. Error Type Mismatch
class2 = Class.forName(className);          // 8. Error Type Mismatch
class3 = Class.forName(className);          // 9. Error Type Mismatch
class1 = Class.forName(className).asSubclass(List.class);   // 10. OK
class2 = Class.forName(className).asSubclass(List.class);   // 11. Error Type Mismatch
class3 = Class.forName(className).asSubclass(List.class);   // 12. Error Type Mismatch

1。,2。和10.是好的,我喜欢10.特别是因为它的清洁,但我不喜欢使用RAW类型,所以我去了通配符。

可悲的是,由于类型不匹配错误,所有其他人都失败了,除非我进行了强制转换加@SuppressWarnings("unchecked")组合。

是否需要使用RAW类型来避免强制转换和@SuppressWarnings("unchecked")

否则如何修复11.和12.? (忘记3到9,他们只是在这里演示不同的组合,我的代码没有使用它们)

1 个答案:

答案 0 :(得分:2)

不幸的是,由于类型擦除的方面,这是语言的基本限制。表示非原始泛型类型的Class个对象不存在,无法获取或创建。即使在==

的比较下,以下表达式都会生成相同的对象
new ArrayList<Integer>().getClass();
new ArrayList<String>().getClass();
Class.forName("java.util.ArrayList");
ArrayList.class;

这会引发ClassNotFoundException

Class.forName("java.util.ArrayList<Integer>");

所以是的,你必须使用原始类型。