当前位置: 首页 > 知识库问答 >
问题:

数字文字的自动装箱:包装初始化与传递方法参数的不一致性

华子昂
2023-03-14
//1
Short s = 10; //obviously compiles    

//2
takeShort(10); //error - int is not applicable

//where:
static void takeShort(Short s) {}
short _temp_s = 10;
Short s = Short.valueOf(_temp_s);

johnchen902答案中对JSL的引用解释了编译器的行为。

仍然不清楚为什么JLS不支持方法调用转换中的“缩窄基元转换,然后是装箱转换”,就像它在赋值转换中支持byte、short、char或int类型的常量表达式一样。有什么想法吗?

共有1个答案

司寇高峯
2023-03-14
Short s = 10;

这是一个赋值转换10是一个常量表达式。JLS说:

赋值转换发生在表达式的值赋给变量时:表达式的类型必须转换为变量的类型。

......

    null
takeShort(10);
    null

如果无法通过方法调用上下文中允许的转换将表达式的类型转换为参数的类型,则会发生编译时错误。

与赋值转换不同,上面列出的non of转换可以将int转换为short,因此会发生编译时错误。

不幸的是,有些人在我批准之前拒绝了Kiruwka的编辑,所以我自己编辑它

// takeInteger(int) takeDouble(double) takeObject(Object) takeIntegerObject(Integer)

takeInteger(5);  // an identity conversion
takeDouble(5);   // a widening primitive conversion
takeObject(new Integer(5)); // a widening reference conversion
takeIntegerObject(5);   // a boxing conversion
takeObject(5);   // a boxing conversion followed by widening reference conversion
takeInteger(new Integer(5)); // an unboxing conversion
takeDouble(new Integer(5)); // an unboxing conversion followed by a widening primitive conversion.
 类似资料:
  • 问题内容: 为什么第二段代码更快? 问题答案: 自动装箱使用,内部将Integer对象缓存为小整数(默认情况下为-128至127,但是最大值可以使用“ java.lang.Integer.IntegerCache.high”属性进行配置-请参见Integer.valueOf的源代码) ,因此与直接调用不同。因为在调用之前可以快速检查整数值的大小,所以直接调用要快一些(尽管如果您有很多小整数,它会使

  • 有以下代码: 它打印: 12 这个不能编译。为什么?

  • 为什么我们可以将int值和char值都赋给Character Wrapper类型。Autoboxing意味着对相应包装进行装箱,但Character不是int的相应包装。它是Integer 为什么这两种说法都是可能的

  • Git 配置 使用Git的第一件事就是设置你的名字和email,这些就是你在提交commit时的签名。 $ git config --global user.name "Scott Chacon" $ git config --global user.email "schacon@gmail.com" 执行了上面的命令后,会在你的主目录(home directory)建立一个叫 ~/.gitco

  • 问题内容: 我想将原语转换为字符串,然后尝试: 失败并显示以下错误: 现在,我知道原语不是引用类型(即不是对象),因此不能有方法。但是,Java 5引入了自动装箱和拆箱功能(一种C#…我在C#中从未喜欢过,但这不重要)。因此,通过自动装箱,我希望上面将myInt转换为Integer,然后在其上调用toString()。 此外,我相信C#允许这样的调用,除非我记错了。这仅仅是Java的自动装箱/拆箱

  • 问题内容: 我想像这样使用Self in init参数: 我知道我可以在这里使用“ A”,但是我想实现这一点,如果某个类从A继承,那么它的初始化器将知道操作是它的类类型,而不仅仅是A。所以例如,如果我这样写: 然后,我可以使用: 这可能吗? 问题答案: 不必使用或在每个初始化器中使用,您可以简单地重写每个子类的初始化器以使用其自己的类型为。 之所以起作用,是因为的初始值设定项声明的类型应符合,并且