为什么我可以将int分配给Short for return类型,但不能在参数列表中?

时间:2018-12-29 15:51:03

标签: java

此代码将无法编译:

class App {
    Short foo() {
        return 3;
    }

    void bar(Short s){

    }

    public static void main(String[] args) {
        new App().foo();
        new App().bar(3);
    }
}

显示以下消息:

App.java:12: error: incompatible types: int cannot be converted to Short
new App().bar(3);

为什么编译器在返回3的{​​{1}}中返回foo时没有问题,但是对于参数Short却不接受3清单?

1 个答案:

答案 0 :(得分:3)

我发现自己在这个问题上走了自己的尾巴,直到阅读JLS并基本上得出结论是,因为Java的创建者是这样做的。

关于new App().bar(3)失败的原因,JLS对于使用装箱方法调用有一条规则:

  

5.3. Method Invocation Conversion
  拳击转换(第5.1.7节)(可选),然后加宽参考转换

在这种情况下,参考转换意味着:

  

假设S是T的子类型(第4.10节),则存在从任何引用类型S到任何引用类型T的扩展引用转换。

因此,编译器会尽力尝试:

new App().bar(new Integer(3))

但是,由于ShortInteger并不是彼此的子类(实际上它们都是Number的两个子类),因此无法进行扩展的引用转换。因此,此方法调用因您看到的编译器错误而失败。

关于允许以下内容的原因:

Short foo() {
    return 3;
}

我们还可以看一下JLS关于分配转换的讨论。埋在里面,我们发现了以下内容:

  

5.2. Assignment Conversion   如果变量的类型为:

,则可以使用紧缩原始转换后跟装箱转换。
  • 字节,常量表达式的值在 输入字节。
  • 简短且常量表达式的值可表示为 短类型。
  • 字符和常量表达式的值是可表示的 字符类型。

因此,编译器可以按以下方式处理foo()方法:

Short foo() {
    return Short.valueOf(3);
}