Soc*_*cke 51 java generics intellij-idea jshell
我有这门课:
class MyClass<N extends Number> {
N n = (N) (new Integer(8));
}
Run Code Online (Sandbox Code Playgroud)
我想得到这些输出:
System.out.println(new MyClass<Long>().n);
System.out.println(new MyClass<Long>().n.getClass());
Run Code Online (Sandbox Code Playgroud)
第一项System.out.println()陈述的输出:
8
Run Code Online (Sandbox Code Playgroud)输出第二个System.out.println()陈述:
java.lang.ClassCastException: java.lang.Integer (in module: java.base)
cannot be cast to java.lang.Long (in module: java.base)
Run Code Online (Sandbox Code Playgroud)为什么我得到第一个输出?是不是也有演员?为什么我在第二个输出中得到异常?
PS:我使用的是Java 9; 我用JShell尝试了它,我在两个输出上都有一个例外.然后我尝试使用IntelliJ IDE并获得第一个输出,但第二个输出异常.
Cal*_*tor 39
IntelliJ显示的行为对我来说很清楚:
你有一个未经检查的演员MyClass.当执行此行时,这意味着new Integer(8)不会立即Long转换为擦除Number(有效):N n =(N)(new Integer(8));
现在让我们看一下输出语句:
System.out.println(new MyClass<Long>().n);
Run Code Online (Sandbox Code Playgroud)
归结为String.valueOf(new MyClass<Long>().n)- > ((Object)new MyClass<Long>().n).toString()工作正常,因为n是通过访问的方式Object,并且toString()方法是通过静态类型访问Object- >没有强制转换Long.new MyClass<Long>().n.toString()会因异常而失败,因为toString()尝试通过静态类型访问Long.因此,Long发生n到类型的转换,这是不可能的(Integer不能转换为Long).
执行第二个语句时会发生同样的事情:
System.out.println(new MyClass<Long>().n.getClass());
Run Code Online (Sandbox Code Playgroud)
试图通过静态类型访问类型的getClass方法(声明Object).因此,会发生n到类型的转换,这会产生强制转换异常.LongLongLong
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)
Run Code Online (Sandbox Code Playgroud)
但似乎JShell提供了与IntelliJ完全相同的结果.System.out.println(new MyClass<Long>().n);输出8 - 没有例外.
Rap*_*aël 25
这是因为Java擦除而发生的.
自Integer扩展以来Number,编译器接受转换为N.在运行时,由于(由于擦除)N取代Number,因此存储Integer内部没有问题n.
方法的参数System.out.println是类型,Object因此打印值的方法没有问题n.
但是,在调用方法时n,编译器会添加类型检查以确保调用正确的方法.因此导致了ClassCastException.
| 归档时间: |
|
| 查看次数: |
2725 次 |
| 最近记录: |