Wrapper 类 - 为什么整型文字对 Long 失败但对任何更小的东西都有效

问题描述 投票:0回答:2

只是想了解自动装箱,除了一件事之外我做的:

Short s = 250;
Long l = 250;

Long l
的分配失败。我预计,这是因为你不能加宽 then box(即它试图将
int
250
加宽到
long
然后将它装箱,这是它做不到的)。

但是,对

Short s
的分配有效。是什么让这一切变得美好?我的假设是它仍在进行装箱和某种转换。但是,如果它知道
250
适合
short
,为什么它不知道
250
适合
long

java wrapper autoboxing
2个回答
15
投票

通常,您不能在赋值中应用多个(隐式)转换(JLS §5.2 赋值转换):

赋值转换发生在将表达式的值赋值给变量(§15.26)时:表达式的类型必须转换为变量的类型。分配上下文允许使用以下之一

  • 身份转换(§5.1.1)
  • 扩大原始转换(§5.1.2)
  • 扩大参考转换(§5.1.5)
  • 装箱转换(§5.1.7)可选地后跟扩大参考转换
  • 拆箱转换(§5.1.8)可选地后跟扩大原始转换。

Long l=250;
需要两次转换(加宽原始转换,然后是装箱转换),这就是它无法编译的原因。

Long l=250l;
编译,因为它需要一次装箱转换。

但是常量表达式的收缩转换是一种特殊情况,这就是为什么

Short s=250;
编译:

此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(§15.28):

  • 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原始转换。
  • 如果变量的类型是:
    • Byte 和常量表达式的值可以用 byte 类型表示。
    • Short 并且常量表达式的值可以用 short 类型表示。
    • 字符和常量表达式的值可以用 char 类型表示。

0
投票

理想情况下,不允许自动缩小。

但是因为没有字节/短文字,我们不能写

byte b = 0b;

这似乎很傻

byte b = (byte)0;

所以常量整数的自动缩小是允许的,所以我们可以写

byte b = 0;

被带到自动装箱盒中。

对于 long/Long,因为有 long 字面值,所以这不是什么问题。不过,它应该被允许,因为有符号整数的自动扩展总是安全的。

© www.soinside.com 2019 - 2024. All rights reserved.