测试ClassCastException时Line2输出特殊信息,咨询对应异常类型
嘿,我来帮你把这个问题理清楚~
先把你的测试代码重新整理一下,方便看清楚结构:
try { class A { } class B extends A {} class C extends A {} A objA = new B(); System.out.println((C)objA); // Line 1 System.out.println((A)objA); // Line 2 } catch (Exception e) { e.printStackTrace(); }
为什么第1行会抛出ClassCastException?
objA的编译类型是A,但实际运行时类型是B。当你尝试把它强制转换成C的时候,JVM会在运行时做类型检查:B和C都是A的子类,但它们彼此之间没有继承关系(B不是C的子类,C也不是B的子类),这种跨平行子类的强制转换是不合法的,所以JVM会直接抛出ClassCastException,这完全符合预期。
第2行为什么没有异常,反而输出对象地址?
第2行的(A)objA属于向上转型,这是Java里完全安全且合法的操作:
- 首先,
objA本身的编译类型已经是A了,而它的实际类型是B(B是A的子类),子类对象天生就可以赋值给父类引用——哪怕你写了显式的强转(A),这其实是多余的,编译器和JVM都会允许这种转换,不会触发任何异常。 - 当你执行
System.out.println((A)objA)时,默认会调用对象的toString()方法,Java中默认的toString()输出格式是全类名@对象哈希码的十六进制值,也就是你看到的exception.RuntimeExceptionTest$1B@7852e922。
简单总结:第2行根本没有触发任何异常,因为这个类型转换是完全合法的,代码直接执行了输出逻辑。
内容的提问来源于stack exchange,提问作者hoapham
相关产品推荐
相关产品推荐

