java - 类<? extends SomeSuperclass> 显然是不允许的。什么有意义呢?

标签 java android generics

这是一个 Android 应用程序,但大概在 Java 中也是如此。我有一个 LevelFactory 类型,我从中派生了 Level1Factory、Level2Factory 等。我想要这些类的数组,这样我就可以在给定数组索引的情况下实例化一个级别。

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

这显然是一个错误“Incompatible types”:

new Class<LevelFactory>[] {Level1Factory.class,Level2Factory.class};

然而,我惊讶地发现这也是一个错误“Generic array creation”:

new Class<? extends LevelFactory>[] {Level1Factory.class,Level2Factory.class};

以下有效,但在分配给变量时会发出“未经检查的分配”警告:

new Class[] {Level1Factory.class,Level2Factory.class};

最后一个是我可以开始工作的唯一选择。我只是忽略了警告,但如果可能的话,我想使用泛型来做到这一点。

最佳答案

我建议您阅读“Effective Java”一书的第 25 项“Prefer lists to arrays”。约书亚·布洛赫 (Joshua Bloch) 写道:

Why is it illegal to create a generic array? Because it isn’t typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a ClassCastException. This would violate the fundamental guarantee provided by the generic type system.

UPD:也许用具体的例子会更容易理解。

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

所以让我们假设有可能有 Set[](但它不是)。如果有人将此数组转换为 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

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

关于java - 类<? extends SomeSuperclass> 显然是不允许的。什么有意义呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11386338/

相关文章:

java - 使用 jQuery/Ajax 将多个选定的复选框发送到 Java

没有带自定义操作的 TabHost 的 Android TabWidget

java - 类 Event<T> 中的构造函数 Event 不能应用于给定类型;找不到符号方法 getTitle()

java - 有没有webhdfs的Java接口(interface)从hadoop集群获取数据

java - 为什么会出现这些错误?

android - ListFragment onListItemClick 不工作

java - 在 “Integer cannot be converted to E[]”中遇到错误,但在其他地方可以使用?

c# - JIT 编译器如何编译泛型?

java - 从 Java 中的参数化类(Apache CXF、Axis2)生成 Web 服务(WSDL 1.2 或更高版本)

java - 是否可以仅使用按位运算符将无符号整数的 4 个小字节序字节分配给 Java 原语?