为什么调用带有 Short 的方法会选择“void (int)”重载而不是“void (Short)”?

Ken*_*hen 5 java boxing overloading

我正在学习Java。当我打电话时go(x),我得到 \xe2\x80\x98int\xe2\x80\x99。为什么不是 \xe2\x80\x98Short\xe2\x80\x99?

\n
public class test {\n    public static void go(Short n) {System.out.println("Short");}\n    public static void go(int n) {System.out.println("int");}\n    \n    public static void main(String[] args) {\n        short x=11;\n        go(x);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Ste*_*n C 4

当您调用重载方法时,编译器需要静态决定将调用哪个重载。直观上,这是通过查看每个重载的签名并根据参数表达式的静态类型找出最佳匹配来完成的。如果存在平局(即没有单个“最佳”匹配),编译器会给出错误,指出方法调用不明确。

这是您的示例的代码。

public class test {
    public static void go(Short n) {System.out.println("Short");}
    public static void go(int n) {System.out.println("int");}
    
    public static void main(String[] args) {
        short x=11;
        go(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

之所以打印“int”而不是“Short”,是因为go(int)它被认为比go(Short)参数表达式的静态类型为 的调用更好匹配short

(从技术上讲,short是 的子类型int,但不是 的子类型Short。)

如果我们将您的代码更改为:

public class test {
    public static void go(short n) {System.out.println("short");}
    public static void go(int n) {System.out.println("int");}
    
    public static void main(String[] args) {
        short x=11;
        go(x);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们现在将看到它short被打印出来。该类型是和的short子类型1,但比 更接近匹配。shortintgo(short)go(int)

Java 语言规范的相关部分是JLS 15.2。但请注意,它又长又复杂……不建议初学者尝试阅读。(事实上​​,我认为大多数Java 程序员并不完全理解它所说的所有内容。包括我自己!)


1 - 这是根据 JLS 中使用的子类型的定义。