[英]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.