【问题标题】:Java Primitive conversions in assignment context Long and int赋值上下文中的 Java 基元转换 Long 和 int
【发布时间】:2013-12-17 10:43:09
【问题描述】:
Long ll = 102; // Error
Byte bb = 101; // No error

为什么Long 赋值会导致编译时错误,而Byte 赋值没问题?

Long ll = 102 导致编译器错误“类型不匹配:无法从 int 转换为 Long”。我假设编译器会将 102 扩大到 long,然后框到 Long。 但它没有发生。

但是Byte bb = 101; 没有产生编译器错误。在这里我猜,101 缩小到byte(非长整数常数),然后装箱到Byte。 收窄没问题,加宽有什么问题?

【问题讨论】:

  • 顺便说一句 Long ll = 102L; 会工作
  • 谢谢。我知道更改代码以避免编译器错误,但我想了解编译器的行为。
  • 顺便说一句,如果可以使用原语,请不要使用对象/包装器,它们更简单、更快。
  • 这种类型的代码是为了考试准备而不是生产代码。
  • @PeterLawrey 对象包装器在 null 是有效值时很有用。我更喜欢使用它而不是 -1 等标记值。

标签: java


【解决方案1】:

这是因为您使用的是Long 而不是long。 Java 自动装箱不会在同一步骤中从int 转换为long,然后将long 自动装箱为Long

将您的代码更改为 long ll 即可。

byte 原语在 java 中没有标记 - 在 byte(-128 到 +127)的有效范围内输入的任何值都可以被视为 byteinteger,具体取决于语境。在这种情况下,它会将其处理为byte,然后自动装箱能够对其进行处理。

我不确定为什么决定让 Java 以这种方式工作。字节处理似乎与所有其他数字类型不一致。

【讨论】:

  • 谢谢。这看起来合乎逻辑。因此,虽然装箱文字是根据目标类型解释的。
【解决方案2】:

5.1.7 Boxing Conversion of the JLS

  • 如果 p 是 int 类型的值,则装箱转换将 p 转换为类和 Integer 类型的引用 r,使得 r.intValue() == p

因为102 是一个整数文字,它的类型是int,并且自动装箱会将其转换为Integer(如规范所述),但不能将Integer 转换为Long

因此,当您使用 long 文字或将 int 文字转换为 long 时,JLS 将使用装箱转换,结果将是 Long 对象。

这样就好了

Long long1 = (long) 102;
Long long2 = 102L;
Long long3 = 102l;

第二个

Byte bb = 101;

有效,因为5.2. Assignment Conversion

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

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

所以101 是一个整数文字,但是有一个需要缩小转换(int -> byte)的赋值,并且int 的值在byte 值范围内。因此它可以表示为变量类型(参见规范)并进行转换。

这当然行不通

 Byte bb = 128; // can not be represented as the variable type. Thus no narrowing conversion.

【讨论】:

  • 自动装箱会将其转换为整数(如规范所述),但不能将整数转换为长整数。那怎么 Integer 可以分配给 Byte(Byte bb = 101 可以正常工作)?
  • 没有说服力。字节 bb = 128;由于超出范围的值而不起作用。但是,当给定范围内的值时,缩小是有效的,但扩大是无效的。这是什么原因。
  • 谢谢,我知道了。非长 const 表达式将被适当地缩小。但永远不会扩大。
  • @user3110711 是的,就是这样。我更新了我的答案以使其更清楚。
【解决方案3】:
  1. 自动装箱也不施放;例如,它只会将long 自动装箱到Long,将int 自动装箱到Integer,等等。
  2. 在 Java 中,数字文字本质上是 int

所以,应该很清楚为什么分配给Long 不起作用:int 正试图被强制转换为long,然后在一步中自动装箱为Long...不去吧。

但是,-128127 范围内的数字文字可能会在正确的上下文中被解释为 byte 文字,这就是分配给 Byte 的原因。

【讨论】:

  • 谢谢。这看起来合乎逻辑。因此,虽然装箱文字是根据目标类型解释的。
猜你喜欢
  • 2021-10-02
  • 1970-01-01
  • 2016-01-07
  • 2020-11-21
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
相关资源
最近更新 更多