gpt4 book ai didi

java - 可变参数和重载的错误?

转载 作者:IT老高 更新时间:2023-10-28 20:47:07 25 4
gpt4 key购买 nike

Java varargs 实现中似乎存在错误。当方法被不同类型的可变参数重载时,Java 无法区分适当的类型。

它给了我一个错误方法...对于类型不明确...

考虑以下代码:

public class Test
{
public static void main(String[] args) throws Throwable
{
doit(new int[]{1, 2}); // <- no problem
doit(new double[]{1.2, 2.2}); // <- no problem
doit(1.2f, 2.2f); // <- no problem
doit(1.2d, 2.2d); // <- no problem
doit(1, 2); // <- The method doit(double[]) is ambiguous for the type Test
}

public static void doit(double... ds)
{
System.out.println("doubles");
}

public static void doit(int... is)
{
System.out.println("ints");
}
}

docs说:“一般来说,你不应该重载可变参数方法,否则程序员将很难弄清楚调用了哪个重载。”

但是他们没有提到这个错误,而且发现困难的不是程序员,而是编译器。

想法?

编辑 - 编译器:Sun jdk 1.6.0 u18

最佳答案

问题在于它模棱两可的。

doIt(1, 2);

可以调用doIt(int ...) , 或 doIt(double ...) .在后一种情况下,整数文字将被提升为 double值(value)观。

我很确定 Java 规范说这是一个模棱两可的构造,编译器只是遵循规范制定的规则。 (我必须进一步研究才能确定。)

编辑 - JLS 的相关部分是“15.12.2.5 Choosing the Most Specific Method”,但这让我很头疼。

<罢工>我认为原因是 void doIt(int[])不比 void doIt(double[]) 更具体(反之亦然)因为int[]不是 double[] 的子类型(反之亦然)。由于两个重载同样具体,因此调用不明确。

相比之下, void doItAgain(int) void doItAgain(double) 更具体因为 intdouble 的子类型根据 JLS。因此,调用 doItAgain(42)不是模棱两可的。

EDIT 2 - @finnw 是对的,这是一个错误。考虑 15.12.2.5 的这一部分(已编辑以删除不适用的情况):

One variable arity member method named m is more specific than another variable arity member method of the same name if:

One member method has n parameters and the other has k parameters, where n ≥ k. The types of the parameters of the first member method are T1, . . . , Tn-1 , Tn[], the types of the parameters of the other method are U1, . . . , Uk-1, Uk[]. Let Si = Ui, 1<=i<=k. Then:

  • for all j from 1 to k-1, Tj <: Sj, and,
  • for all j from k to n, Tj <: Sk

将此应用于 n = k = 1 的情况,我们看到 doIt(int[])doIt(double[]) 更具体.


其实有一个bug report对于这个 ,Sun 承认这确实是一个错误,尽管他们已将其列为“非常低” 。该错误现在在 Java 7 (b123) 中被标记为已修复。

关于java - 可变参数和重载的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2521293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com