Why does invoking a method with a short choose the `void (int)` overload over `void (Short)`?

huangapple go评论52阅读模式
英文:

Why does invoking a method with a short choose the `void (int)` overload over `void (Short)`?

问题

I am learning Java. When I call go(x), I get 'int'. Why not 'Short'?

我正在学习Java。当我调用 go(x) 时,我得到 'int'。为什么不是 'Short'?

英文:

I am learning Java. When I call go(x), I get ‘int’. Why not ‘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);
	}
}

答案1

得分: 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);
    }
}

之所以输出“int”而不是“Short”,是因为编译器认为 go(int)go(Short) 更匹配一个参数表达式的静态类型为 short 的调用。

(严格来说,shortint 的子类型,但不是 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);
    }
}

现在会输出“short”。类型 shortshortint 的子类型1,但 go(short)go(int) 更匹配。

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


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

英文:

When you make a call to an overloaded method, the compiler needs to decide statically which of the overloads will be called. Intuitively, this is done by looking at each of the overloads' signatures, and working out which one is the best match ... based on the static types of the argument expressions. If there is a tie (i.e. no single "best" match), the compiler gives an error saying that the method call is ambiguous.

This is the code of your example.

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

The reason that this prints "int" rather than "Short" is because go(int) is deemed to be a better match than go(Short) to a call where the argument expression's static type is short.

(Technically, short is a subtype of int, but not of Short.)

If we change your code to this:

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

we will now see that short is printed. The type short is a subtype<sup>1</sup> of both short and int, but go(short) is a closer match than go(int).

The relevant section of the Java Language Specification is JLS 15.2. But beware that is long and complicated ... and NOT recommended for beginners to try to read. (Indeed, I would posit that most Java programmers don't fully understand all of what it says. Myself included!)


<sup>1 - This is according to the definition of subtype used in the JLS.</sup>

huangapple
  • 本文由 发表于 2023年5月14日 18:20:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76246945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定