可变参数 Java 歧义调用 [英] Varargs Java Ambiguous Call

查看:15
本文介绍了可变参数 Java 歧义调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Java 的 varargs 方法有点困惑:

public static int sum(int ...a) {返回0;}公共静态双和(双...a){返回 0.0;}

当我尝试在不传递任何参数的情况下调用 sum() 时,会调用方法的 int 版本.我不明白为什么;通常编译器必须引发错误.

相比之下,当我尝试不带任何参数调用 sum 时,以下代码会生成编译器错误:

public static int sum(int ...a) {返回0;}公共静态布尔总和(布尔...a){返回真;}

解决方案

这里适用的一般规则是:如果一个方法签名比另一个严格更具体,那么 Java 选择它而不是一个错误.

直观地说,如果您可以完全删除它,则方法签名会更具体,而另一个不太具体的方法签名则适用于每个现有调用.

当在签名 sum(int... args)sum(double... args) 之间进行选择时,签名 sum(int... args) 更具体,因为该方法的任何调用也可以通过应用扩展转换传递给 sum(double... args).对于 sum(boolean... args) 方法,同样的情况不成立,它不能被类似地转换.

Java 语言规范,SE 8 版本:

<块引用>

15.12.方法调用表达式

15.12.2.5.选择最具体的方法

Java 编程语言使用的规则是选择最具体的方法.

...

一个适用的方法 m1 比另一个适用的方法 m2 更具体,对于带有参数表达式 e1, ..., ek 的调用,如果以下任何一项为真:

...

  • m2 不是泛型的,m1 和 m2 可以通过严格调用或松散调用来应用,并且其中 m1 具有形式参数类型 S1, ..., Sn 和 m2 具有形式参数类型 T1, ..., Tn,类型对于所有 i (1 ≤ i ≤ n, n = k),Si 比 Ti 的参数 ei 更具体.

...

对于任何表达式,如果 S <: T,则类型 S 比类型 T 更具体(第 4.10 节).

<小时><块引用>

4.10.子类型

4.10.1.原始类型之间的子类型化

double >1 float

浮动 >1 长

long >1 int

I'm a little confused about Java's varargs methods:

public static int sum(int ...a) {
    return 0;
}

public static double sum(double ...a) {
    return 0.0;
}

When I tried to invoke sum() without passing any argument, then the int version of method was invoked. I don't understand why; normally the compiler must raise an error.

By contrast, the following piece of code generates a compiler error when I try to invoke sum without any argument:

public static int sum(int ...a) {
    return 0;
}

public static boolean sum(boolean ...a) {
    return true;
}

解决方案

The general rule that applies here is this: if one method signature is strictly more specific than the other, then Java chooses it without an error.

Intuituively, a method signature is more specific if you could delete it entirely and the other, less specific one would be applicable to each existing invocation.

When presented with a choice between the signatures sum(int... args) and sum(double... args), the signature sum(int... args) is more specific because any invocation of that method could also be passed on to sum(double... args) by applying a widening conversion. The same does not hold for a sum(boolean... args) method, which cannot be similarly converted.

Java Language Specification, SE 8 version:

15.12. Method Invocation Expressions

15.12.2.5. Choosing the Most Specific Method

The Java programming language uses the rule that the most specific method is chosen.

...

One applicable method m1 is more specific than another applicable method m2, for an invocation with argument expressions e1, ..., ek, if any of the following are true:

...

  • m2 is not generic, and m1 and m2 are applicable by strict or loose invocation, and where m1 has formal parameter types S1, ..., Sn and m2 has formal parameter types T1, ..., Tn, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ n, n = k).

...

A type S is more specific than a type T for any expression if S <: T (§4.10).


4.10. Subtyping

4.10.1. Subtyping among Primitive Types

double >1 float

float >1 long

long >1 int

这篇关于可变参数 Java 歧义调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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