IntelliJ显示的行为对我来说很清楚:
您在System.out.println(new MyClass().n);中有一个未经检查的演员表。这意味着执行此行时,不是立即将Object投射到Long,而是擦除Long(起作用):Long
现在让我们看一下输出语句:
System.out.println(new MyClass().n);
可以归结为System.out.println(new MyClass().n);-> Object,这很好用,因为通过Long访问n以及通过静态类型Long访问Long方法->没有强制转换为Long。 new MyClass().n.toString()可能会失败,因为会尝试通过静态类型Long访问toString()。因此,将n转换为Long类型是不可能的(Integer无法转换为Long)。
执行第二条语句时会发生相同的事情:
System.out.println(new MyClass().n.getClass());
尝试通过静态类型Long访问类型Long的System.out.println(new MyClass().n);方法(在Object中声明)。因此,发生将n强制转换为Long的类型,这会产生强制转换异常。
JShell行为:
我试图在JShell-Java 9早期访问Build 151上重现第一条输出语句的结果异常:
jshell> class MyClass {
...> N n = (N) (new Integer(8));
...> }
| Warning:
| unchecked cast
| required: N
| found: java.lang.Integer
| N n = (N) (new Integer(8));
| ^--------------^
| created class MyClass
jshell> System.out.println(new MyClass().n);
8
jshell> System.out.println(new MyClass().n.getClass());
| java.lang.ClassCastException thrown: java.base/java.lang.Integer cannot be cast to java.base/java.lang.Long
| at (#4:1)
但似乎JShell提供的结果与IntelliJ完全相同。 System.out.println(new MyClass().n);输出8-也不例外。