rge*_*man 20
JLS的5.2节介绍了赋值上下文中允许的转换类型.
赋值上下文允许使用以下之一:
身份转换(§5.1.1)
扩展的原始转换(第5.1.2节)
扩大参考转换(第5.1.5节)
一个拳击转换(§5.1.7),可选地后跟一个加宽的引用转换
另外,
此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):
如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示.
如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:
字节和常量表达式的值可在类型字节中表示.
Short和常量表达式的值可以在short类型中表示.
字符和常量表达式的值可在char类型中表示.
Byte b = 10编译好因为10是一个常量表达式并且可以表示为byte.
Byte b = new Byte(10)将不会编译因为10是int文字,并且方法调用转换不会执行原始缩小转换.要调用Byte构造函数进行编译,可以显式转换10为byte:
Byte b = new Byte( (byte) 10);
Run Code Online (Sandbox Code Playgroud)
Long l = new Long(10)编译因为方法调用转换将执行原始扩展转换,包括from int到long.
Long l = 10不会编译,因为Java不会特别允许扩展转换,然后进行装箱转换,正如我在最近的回答中所讨论的那样.要使其编译,您可以使用long文字,因此只需要装箱.
Long l = 10L;
Run Code Online (Sandbox Code Playgroud)
ysh*_*vit 10
基本规则是:
这些规则解释了为什么Long l = 10不起作用,以及new Byte(10).第一个要求将int literal 10扩展为a long然后加框,这是不允许的.(更准确地说,它需要转换int为Long,JLS 5.1.7没有定义.)第二个要求将int literal 10隐式缩小为a byte,这是不允许的.
但该规则有例外.JLS 5.2Byte b = 10明确允许:
此外,如果表达式类型的常量表达式(§15.28) ,
byte,short,char或int:
- 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:
Byte并且常量表达式的值可在类型中表示byte.
(省略了一些不相关的部分)
最后,new Long(10)因为int literal 10 可以自动加宽到10L.
10 是一个整数文字,您必须将其向下转换才能将其传递给 Byte 构造函数。不幸的是,也没有字节文字语法可以删除强制转换。
另外,为什么 Long l = new Long(10) 编译正常但 Long l = 10 失败?
因为 10 作为一个整数,可以毫无问题地放入 long 中。整数无法放入字节中,因此在这种情况下需要进行强制转换(扩大转换)。
此转换也是编译时,因为它也是扩大转换。查看 JLS 中的第 5.1.5 节:
加宽引用转换在运行时不需要特殊操作,因此永远不会在运行时抛出异常。它们只是将引用视为具有某种其他类型,并且可以在编译时证明其正确性。
| 归档时间: |
|
| 查看次数: |
3571 次 |
| 最近记录: |