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

Java 为什么我可以将int赋值给Short for return类型,但不在参数列表中?,java,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

此代码不会编译:

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);

为什么编译器在
foo
中返回
3
时没有问题,它的返回类型为
Short
,但对于参数列表中的
Short
,编译器不会接受
3

我发现自己在这个问题上一直在追根究底,直到我阅读了JLS,基本上得出结论,答案是,因为Java的创建者就是这样做的

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


装箱转换(§5.1.7)后可选加宽参考转换

在此上下文中,引用转换意味着:

如果S是T的子类型(§4.10),则存在从任何参考类型S到任何参考类型T的扩展参考转换

因此,编译器将尝试:

new App().bar(new Integer(3))
但是由于
Short
Integer
不是彼此的子类(它们实际上都是
Number
的子类),因此不可能进行更广泛的引用转换。因此,此方法调用失败,出现了您看到的编译器错误

至于为什么允许以下情况:

Short foo() {
    return 3;
}
我们还可以参考JLS关于任务转换的讨论。埋在那里,我们发现如下:

如果变量的类型为:
,则可以使用紧跟装箱转换的缩小原语转换

  • 字节和常量表达式的值可在 键入byte
  • Short,常量表达式的值可表示为 字体很短
  • 字符和常量表达式的值是可表示的 在类型char中
因此,编译器可以按如下方式处理
foo()
方法:

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

尝试使用一个不适合短范围的文字。还可以试试当你试图返回一个int变量时会发生什么……我认为他的观点是,他*正在*使用一个文本,并且该文本在一个短的范围内。我也有点困惑这是如何工作的。我认为在
return3您实际上创建了一个简短的文字,而不需要任何强制转换。是的,这就是正在发生的事情,但为什么在另一种情况下不也会发生呢?我错了(请参见公认的答案),但是如果我删除了我的注释,那么最后一条注释就没有意义了。