【问题标题】:assigning int literal to Long in java [duplicate]在java中将int文字分配给Long [重复]
【发布时间】:2016-10-25 07:39:00
【问题描述】:

我认为没有明确的理由发生这种情况..

public  class wrappers
{
    public static void main(String []args)
    {
        short s1=32767; // (primitive) works fine without compile error
        short s2=32768;   fails as this is  beyond short's range


        Short s3=32767; //(wrapper) works fine without compile error
        Short s4=32768; fails as this is beyond short's range

        long l1 =34   // (wrapper)works fine (with_in_range)


        Long l2 =34    // fails, without 34L (with_in_range)

    }

我知道,当您为包装类分配 int 文字时,会调用 valueOf()

对于Short(Wrapper),这似乎可行,但对于Long(wrapper),上述代码中的分配失败。

是否有任何规则来管理这些包装类的分配?

【问题讨论】:

  • 您找到了一个不错的角包。我相信,Short s4 = 32767 也不应该工作。无论如何,您可以像这样修复Long 的情况:Long l1 = 12L; // capital L。为了记录,这个术语叫做Autoboxing,你可以用谷歌搜索。
  • 是的,有规则。他们被称为Java Language Specifications
  • 您没有转换值。就像int a = 100.1 不能编译一样,上面也一样。
  • @TamasRev 我想短距离是 -32768 到 32767,我知道这是自动装箱,这个赋值是 valueOf 的语法糖

标签: java wrapper literals primitive


【解决方案1】:

是否有任何规则管理这些包装类的分配

是的 - JLS 的规则。它指定了widening primitive conversions (5.1.2)boxing conversions (5.1.7)

拳击转换列表包括:

  • int 类型到Integer 类型
  • long 类型到Long 类型

因此,您需要先扩大转换,然后再进行装箱转换。您正在尝试在 assignment context (5.2) 中执行此操作,其中指出:

分配上下文允许使用以下之一:

  • 身份转换 (§5.1.1)
  • 扩大的基元转换 (§5.1.2)
  • 扩大参考转换 (§5.1.5)
  • 装箱转换(第 5.1.7 节)可选地后跟扩大参考转换
  • 拆箱转换(第 5.1.8 节)可选地后跟加宽基元转换。

请注意,此列表包括加宽原始转换后跟装箱转换。反过来就好了:

Integer x = 10;
long y = x; // Unboxing followed by widening primitive

从表面上看,听起来规则可以被编写为允许扩大原始转换,然后进行装箱转换,其中Object x = 10; 更喜欢装箱作为Integer 的规则而不是Long... 但类型转换规则非常很难正确,有很多微妙之处。如果事实证明有一些奇怪的情况会导致大问题,我不会感到惊讶。

转换为Short 起作用的原因是由于 5.2 中的进一步规则:

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

  • 如果变量的类型是byteshortchar,并且常量表达式的值可以在变量的类型中表示,则可以使用缩小原语转换。
  • 如果变量的类型为:
    • Byte 和常量表达式的值可以用byte 类型表示。
    • Short 和常量表达式的值可以用 short 类型表示。
    • Character 和常量表达式的值可以用 char 类型表示。

如果是

Short s = 32767;

有一个缩小的原始转换,然后是一个装箱转换,如上所述。

【讨论】:

  • 对于Short s3=32767; 情况,您还应该提及允许缩小原始转换后跟装箱转换的部分。
  • 你没有解释为什么 Short s3=32767 有效,因为文字 32767 被定义为 int 文字,所以它应该失败。
  • @Andreas:已经添加了额外的部分。
  • @user2357112:现在已经完成了。
【解决方案2】:

自动装箱仅在原始类型和它们各自的包装类之间完成,例如:

int 到整数,

长到长

加倍到加倍等等。

Java 不允许原始类型 int 和 Object Long 之间的转换。 但是,它确实允许在原始类型 int 和 long 之间进行转换。 因此,如果您需要将 int 分配给 Long 类型的变量,您需要添加后缀 lL

  Long l2 =34L,

【讨论】:

    【解决方案3】:

    为了扩展 Jon 的答案,JLS 中还指定了允许 Short s3=32767 工作的规则。关于常量表达式的赋值有一个特殊的规则:

    5.2. Assignment Contexts
    ...

    此外,如果表达式是常量表达式(§15.28) 输入 byte、short、char 或 int

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

    • 如果变量的类型为

      ,则可以使用紧跟原始转换后的装箱转换
      1. 字节和常量表达式的值可以用字节类型表示。

      2. Short,常量表达式的值可以用short类型表示。

      3. 字符和常量表达式的值可以用char类型表示。

    【讨论】:

      猜你喜欢
      • 2017-07-30
      • 1970-01-01
      • 2011-10-26
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多