数字文字的自动装箱:包装器初始化与传递方法参数不一致 [英] autoboxing of numeric literals : wrapper initialization vs passing method arguments inconsistency

查看:23
本文介绍了数字文字的自动装箱:包装器初始化与传递方法参数不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑两种情况:

//1
Short s = 10; //obviously compiles    

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

//where:
static void takeShort(Short s) {}

我假设情况 1 被编译器更改为:

I assume that case 1 is changed by compiler to :

short _temp_s = 10;
Short s = Short.valueOf(_temp_s);

你能解释一下编译器在情况 2 中试图做什么,所以它不能编译吗?如果它不像情况 1 那样尝试应用自动装箱,那为什么?

Could you please explain what compiler is trying to do in case 2, so it does not compile ? If it is not trying to apply autoboxing as it does in case 1, then why ?

编辑

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

Reference to JSL in johnchen902 answer explains compiler's behaviour.

仍然不完全清楚为什么 JLS 不支持方法调用转换的缩小原语转换,然后是装箱转换",因为它在字节、short、char 或 int 类型的常量表达式的情况下在赋值转换中支持.有什么想法吗?

Still not exactly clear why JLS does not support "A narrowing primitive conversion followed by a boxing conversion" for Method Invocation Conversion as it does in Assignment Conversion for the case of constant expression of type byte, short, char, or int. Any ideas ?

推荐答案

Short s = 10;

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

This is an Assignment Conversion, and 10 is a constant expression. JLS said:

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

5.2. Assignment Conversion

Assignment conversion occurs when the value of an expression is assigned to a variable: the type of the expression must be converted to the type of the variable.

......

另外,如果表达式是byte、short、char或int类型的常量表达式:

In addition, if the expression is a constant expression of type byte, short, char, or int:

  • 如果变量的类型是:
    • Short 并且常量表达式的值可以在类型 short 中表示.


    takeShort(10);
    

    这是一个方法调用转换.JLS 说:

    方法调用转换应用于方法或构造函数调用中的每个参数值:参数表达式的类型必须转换为相应参数的类型.

    5.3. Method Invocation Conversion

    Method invocation conversion is applied to each argument value in a method or constructor invocation : the type of the argument expression must be converted to the type of the corresponding parameter.

    方法调用上下文允许使用以下之一:

    Method invocation contexts allow the use of one of the following:

    • 身份转换
    • 扩大原始转换
    • 扩大参考转换
    • 可选的装箱转换后跟扩展引用转换
    • 一个拆箱转换(可选)后跟一个扩大的原始转换.

    ......

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

    与赋值转换不同,上面列出的非转换可以将int转换为Short,因此会出现编译时错误.

    Unlike Assignment Conversion, non of conversion listed above can converts int to Short, so a compile-time error occurs.

    很遗憾,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.
    

    这篇关于数字文字的自动装箱:包装器初始化与传递方法参数不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆