[英]Why can't I cast an array of Objects to an array of a generic subclass of a generic class?
此代码有效。 它编译并运行时会出现“未经检查或不安全的操作”警告。
class Foo<T> {
T[] items = (T[]) new Object[10];
public static void main(String[] args) {
Foo<Integer> foo = new Foo<Integer>();
}
}
虽然这两个给了我运行时错误
class Foo<T> {
class FooItem { T item; }
FooItem[] items = (FooItem[]) new Object[10];
public static void main(String[] args) {
Foo<Integer> foo = new Foo<Integer>();
}
}
class Foo<T> {
static class FooItem<E> { E item; }
FooItem<T>[] items = (FooItem<T>[]) new Object[10];
public static void main(String[] args) {
Foo<Integer> foo = new Foo<Integer>();
}
}
我遇到的错误如下:
线程“主”中的异常 java.lang.ClassCastException: class [Ljava.lang.Object; 不能转换为 class [LFoo$FooItem; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [LFoo$FooItem; is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader
为什么是这样?
您的Foo
class 的所有版本都有同样的问题。 Type safety: Unchecked cast from Object[] to X
警告您忽略的只是在执行期间的不同阶段显示其后果。
这是破坏您的第一个版本的方法:
class Foo<T> {
T[] items = (T[]) new Object[10];
public static void main(String[] args) {
Foo<Integer> foo = new Foo<Integer>();
Integer i = foo.items[1] * 2;
}
}
它崩溃了......同样的问题:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at stackoverflow.Foo.main(Main.java:17)
为什么? 因为(T[]) new Object[10];
在编译时不强制执行,即编译器不知道如何验证T[]
和Object[]
之间的关系
就像您不能将new Object()
转换为Integer
,您也不能将new Object[10]
转换为Integer[]
。 只是这个 class 转换异常仅在运行实际转换时出现。 对于第一个片段,它不在声明语句上运行, T[] items = (T[]) new Object[10];
(因此警告),但是当items
用作T
的类型参数时。
您的其他版本会更快地显示问题,因为它们正在转换为具体类型,例如(FooItem[]) new Object[10]
,导致声明语句本身崩溃。
为什么编译器允许这种转换? 因为类型关系是有效的,给定这样的代码
Object[] items = new Integer[10];
Integer[] i = (Integer[])items;
Integer val = i[0];
有效且受支持。
不能将Object[]
转换为T[]
的原因是这可能会导致以下代码出现问题:
Object[] objects = new Object[10]; // This is fine
objects[0] = "Hello World"; // Is fine since String is subtype of Object
T[] ts = (T[]) objects; // One could argue that this is fine
T firstT = ts[0]; // Now we have the issue that String needs to be casted to T
因此,不允许将Object[]
转换为T[]
。 generics 类似列表的情况也是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.