IntelliJ显示的行为对我来说很清楚:
您在 中有一个未经检查的转换。这意味着在执行此行时,不会立即强制到擦除(有效)中:MyClass
new Integer(8)
Long
Number
N n =(N)(new Integer(8));
现在让我们看一下输出语句:
System.out.println(new MyClass<Long>().n);
归结为 -> 这工作正常,因为 n 是通过访问的,并且该方法也是通过静态类型 ->不会发生强制转换。 将失败并显示异常,因为 尝试通过静态类型 访问 。因此,发生 n 到类型的强制转换是不可能的(不能强制转换为 )。String.valueOf(new MyClass<Long>().n)
((Object)new MyClass<Long>().n).toString()
Object
toString()
Object
Long
new MyClass<Long>().n.toString()
toString()
Long
Long
Integer
Long
执行第二条语句时也会发生同样的事情:
System.out.println(new MyClass<Long>().n.getClass());
尝试通过静态类型 访问类型的方法(在 中声明)。因此,发生 n 到类型的强制转换,从而产生强制转换异常。getClass
Object
Long
Long
Long
JShell 行为:
我试图重现JShell上第一个输出语句的结果异常 - Java 9早期访问Build 151:
jshell> class MyClass<N extends Number> {
...> 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<Long>().n);
8
jshell> System.out.println(new MyClass<Long>().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完全相同的结果。 产出8 - 无一例外。System.out.println(new MyClass<Long>().n);