作为java.lang.Object结果的泛型不能转换为[Ljava.lang.Object]
任何人都可以解释为什么泛型作为java.lang.Object结果的泛型不能转换为[Ljava.lang.Object],java,generics,classcastexception,generic-list,Java,Generics,Classcastexception,Generic List,任何人都可以解释为什么泛型会导致ClassCastException(运行时异常!) 我知道所有的泛型都是在编译阶段删除的,对字节码没有任何影响,但似乎有些细微差别 下面是我的示例(本文简化): 我不明白这段代码出了什么问题。有人能解释一下这种行为吗?为什么要在对象数组列表中强制转换它 尝试对象列表,它将工作 import java.util.ArrayList; import java.util.List; public class CastTest { public static
会导致ClassCastException
(运行时异常!)
我知道所有的泛型都是在编译阶段删除的,对字节码没有任何影响,但似乎有些细微差别
下面是我的示例(本文简化):
我不明白这段代码出了什么问题。有人能解释一下这种行为吗?为什么要在对象数组列表中强制转换它 尝试对象列表,它将工作
import java.util.ArrayList;
import java.util.List;
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Object());
List<Object> b = a;
b.get(0).toString();
}
}
import java.util.ArrayList;
导入java.util.List;
公共类测试{
公共静态void main(字符串[]args){
列表a=新的ArrayList();
a、 添加(新对象());
清单b=a;
b、 get(0.toString();
}
}
为什么要在对象数组列表中强制转换它
尝试对象列表,它将工作
import java.util.ArrayList;
import java.util.List;
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Object());
List<Object> b = a;
b.get(0).toString();
}
}
import java.util.ArrayList;
导入java.util.List;
公共类测试{
公共静态void main(字符串[]args){
列表a=新的ArrayList();
a、 添加(新对象());
清单b=a;
b、 get(0.toString();
}
}
如果您这样看,可能会更清楚:
import java.util.ArrayList;
import java.util.List;
class Dog { }
class Cat { }
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Dog());
List<Cat> b = a;
Cat c = b.get(0);
}
}
$ java CastTest
Exception in thread "main" java.lang.ClassCastException: Dog cannot be cast to Cat
at CastTest.main(CastTest.java:12)
如果确实希望它是一个对象数组列表,则必须添加一个对象数组:
import java.util.ArrayList;
import java.util.List;
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Object[]{});
List<Object[]> b = a;
System.out.println(b.get(0).toString());
}
}
$ java CastTest
[Ljava.lang.Object;@65685e30
import java.util.ArrayList;
导入java.util.List;
公共类测试{
公共静态void main(字符串[]args){
列表a=新的ArrayList();
a、 添加(新对象[]{});
清单b=a;
System.out.println(b.get(0.toString());
}
}
$java CastTest
[Ljava.lang.Object;@65685e30
如果您这样看,可能会更清楚:
import java.util.ArrayList;
import java.util.List;
class Dog { }
class Cat { }
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Dog());
List<Cat> b = a;
Cat c = b.get(0);
}
}
$ java CastTest
Exception in thread "main" java.lang.ClassCastException: Dog cannot be cast to Cat
at CastTest.main(CastTest.java:12)
如果确实希望它是一个对象数组列表,则必须添加一个对象数组:
import java.util.ArrayList;
import java.util.List;
public class CastTest {
public static void main(String[] args) {
List a = new ArrayList();
a.add(new Object[]{});
List<Object[]> b = a;
System.out.println(b.get(0).toString());
}
}
$ java CastTest
[Ljava.lang.Object;@65685e30
import java.util.ArrayList;
导入java.util.List;
公共类测试{
公共静态void main(字符串[]args){
列表a=新的ArrayList();
a、 添加(新对象[]{});
清单b=a;
System.out.println(b.get(0.toString());
}
}
$java CastTest
[Ljava.lang.Object;@65685e30
正如其他人所说,因为对象
不是对象[]
短语java.lang.Object中有提示,不能将其强制转换为[Ljava.lang.Object
根据,[Ljava.lang.Object
的意思是:
-数组[
-一个类L
因此,
java.lang.Object不能转换为[Ljava.lang.Object
可以理解为对象不能转换为对象数组,正如其他人所说,因为对象
不是对象[]
短语java.lang.Object中有提示,不能将其强制转换为[Ljava.lang.Object
根据,[Ljava.lang.Object
的意思是:
-数组[
-一个类L
因此,
java.lang.Object不能强制转换为[Ljava.lang.Object
可以被读取为对象不能强制转换为对象数组您告诉编译器您要调用Object[].toString()
。这就是编译器生成强制转换(checkcast
)的原因:
您告诉编译器要调用
对象[]。toString()
。这就是编译器生成强制转换(checkcast
)的原因:
这是因为编译器坏了
b.get(0).toString();
深入
Object[] temp = b.get(0);
temp.toString();
Object temp = b.get(0);
temp.toString();
当被擦除时,具有对对象[]
的强制转换
现在可以说,编译器也可以选择将其分解为
Object temp = b.get(0);
temp.toString();
因为引用仅用于调用
.toString()是在对象上声明的。如果它这样做了,它将避免强制转换。然而,为什么编译器会投入额外的分析工作,以不同的方式做一些事情,而这只在您使用错误的类型时才起作用呢?这是因为编译器坏了
b.get(0).toString();
深入
Object[] temp = b.get(0);
temp.toString();
Object temp = b.get(0);
temp.toString();
当被擦除时,具有对对象[]
的强制转换
现在可以说,编译器也可以选择将其分解为
Object temp = b.get(0);
temp.toString();
因为引用仅用于调用.toString()
是在对象上声明的,如果它这样做了,它将避免强制转换。然而,为什么编译器会投入额外的分析工作,以不同的方式做一些事情,而这只会在您使用错误的类型时才起作用呢?因为a
包含对象,而不是对象[]
。这并不重要,我在本例中没有使用任何强制转换。它是隐式完成的。您能解释一下这是怎么可能的吗?因为类型擦除()不允许泛型在运行时执行某些操作,因为对象[]对象的实例
为true
,没有编译错误的原因。因为a
包含Object
,而不是Object[]
。这不重要,我在本例中没有使用任何强制类型转换。它是隐式完成的。您能解释一下这是怎么可能的吗?因为类型擦除()不允许泛型在运行时执行某些操作,因为Object[]对象的实例
为true
,没有编译错误的原因。Why-它是另一个问题,让我们同意此强制转换需要某些原因:-)我理解如果我删除所有的将很好。Why-它是另一个问题,让我们同意此强制转换需要某些原因:-)我理解如果我删除所有的将很好ion,但没有回答为什么JVM在listHi中尝试强制转换项,@Akvel,请参阅我的最新编辑,以查看字节码中生成的强制转换,如您在上面提供的链接(docs.oracle.com/javase/tutorial/java/generics/erasure.html)中所述如果有必要,编译器将插入类型强制转换,以保持类型安全。这是一个解决方案,但没有回答为什么JVM在listHi中尝试强制转换项目,@Akvel,请参阅我的最新编辑以查看在字节码中生成的强制转换,如上面提供的链接所述(docs.oracle.com/javase/tutorial/java/generics/erasure.html)