类<?显然不允许扩展SomeSuperclass>.有什么意义呢?

Hap*_*eer 1 java generics android

这是一个Android应用程序,但可能在Java中也是如此.我有一个类型LevelFactory,我从中导出Level1Factory,Level2Factory等.我想拥有这些类的数组,所以我可以实例化给定数组索引的级别.

我可以只有一个Class []并将它们放入其中然后在我需要使用它们时将它们转换为LevelFactory,但我想知道正确的做法是什么.

这显然是一个错误"不兼容的类型":

new Class<LevelFactory>[] {Level1Factory.class,Level2Factory.class};
Run Code Online (Sandbox Code Playgroud)

但是,我很惊讶地发现这也是一个错误"通用数组创建":

new Class<? extends LevelFactory>[] {Level1Factory.class,Level2Factory.class};
Run Code Online (Sandbox Code Playgroud)

以下工作,但它在分配给变量时给出"未选中分配"警告:

new Class[] {Level1Factory.class,Level2Factory.class};
Run Code Online (Sandbox Code Playgroud)

最后一个是我可以开始工作的唯一选择.我只是忽略了警告,但如果实际上可行,我想用泛型来做.

Dmi*_*rev 5

我建议你阅读"Effective Java"一书的第25项"首选列表到数组".Joshua Bloch写道:

为什么创建通用数组是非法的?因为它不是类型安全的.如果它是合法的,那么编译器在正确的程序中生成的强制转换可能会在运行时因ClassCastException而失败.这将违反通用类型系统提供的基本保证.

UPD:也许有具体的例子,它会更容易理解.

首先,数组是协变的,这意味着SuperClass []可以转换为SubClass [],反之亦然.这也意味着将AnyConcreteClass []强制转换为Object []是合法的.

所以我们假设Set <Cat> []是可能的(但它不是).如果有人将此数组转换为Object []然后在其中添加一组Dog实例,则Java无法保证我们的数组仅包含Cat实例集.打破类型安全它打破了泛型的本质.这就是为什么它是非法的通用阵列.

Set<Cat>[] cats = new Set<Cat>[]; // illegal
Object[] objects = cats;
objects[1] = new Set<Dog>();
cats[1].add(new Cat()); // Oops! TypeCastException
Run Code Online (Sandbox Code Playgroud)

老实说这个例子也取自Effective Java :)