Java 可变参数方法重载编译器错误 - 歧义?
Java varargs method overloading compiler error - ambiguity?
所以,今天我一直在测试 Java 的重载技术,但遇到了我无法解释的歧义。基本上,当存在带有原语及其相应包装器的可变参数方法时,编译器会抱怨并且无法决定选择哪一个,我不明白为什么?人类很容易决定而不是编译器?
这是适用于非可变参数的片段:
public static void main(String[] args)
{
int a = 14;
Integer b = new Integer(14);
stuff(a);
stuff(b);
}
static void stuff(Integer arg) { System.out.println("Integer"); }
static void stuff(int arg) { System.out.println("int"); }
来了 vararg,它像婴儿一样抱怨和哭泣:
public static void main(String[] args)
{
int a = 14;
Integer b = new Integer(14);
stuff(a); // Doesn't compile (ambiguity)
stuff(b); // Doesn't compile (ambiguity)
}
static void stuff(int... arg) { System.out.println("varargs int"); }
static void stuff(Integer... arg) { System.out.println("varargs Integer"); }
问题是:
java 正在幕后进行桥接方法(您需要验证是否需要深入信息)
重要的是,vargargs 也意味着 你不能传递任何参数,所以:
static void stuff(int... arg)
和
static void stuff(Integer... arg)
两者都可以在不带参数的情况下被调用...所以这将在 JVM 应该调用什么方法方面产生一些冲突
考虑以下对 stuff()
的两个假设调用:
int a = 14;
Integer b = new Integer(14);
stuff(a, b);
stuff(b, a);
编译器怎么知道应该在这里调用哪个方法?由于自动装箱规则,任一调用都可以引用任一重载方法。
更新:
我的回答在逻辑上是正确的,或者至少是在正确的轨道上,但是更正式的回答我们可以参考这个SO问题:
Why ambiguous error when using varargs overloading with primitive type and wrapper class?
这两个可变参数方法是在松散调用上下文中调用的。因此,编译器将尝试通过 JLS 15.12.2.5 Choosing the Most Specific Method 找到更具体的方法。但是,由于 int
和 Integer
都不是彼此的子类型,因此编译器会抛出错误。
所以,今天我一直在测试 Java 的重载技术,但遇到了我无法解释的歧义。基本上,当存在带有原语及其相应包装器的可变参数方法时,编译器会抱怨并且无法决定选择哪一个,我不明白为什么?人类很容易决定而不是编译器?
这是适用于非可变参数的片段:
public static void main(String[] args)
{
int a = 14;
Integer b = new Integer(14);
stuff(a);
stuff(b);
}
static void stuff(Integer arg) { System.out.println("Integer"); }
static void stuff(int arg) { System.out.println("int"); }
来了 vararg,它像婴儿一样抱怨和哭泣:
public static void main(String[] args)
{
int a = 14;
Integer b = new Integer(14);
stuff(a); // Doesn't compile (ambiguity)
stuff(b); // Doesn't compile (ambiguity)
}
static void stuff(int... arg) { System.out.println("varargs int"); }
static void stuff(Integer... arg) { System.out.println("varargs Integer"); }
问题是:
java 正在幕后进行桥接方法(您需要验证是否需要深入信息)
重要的是,vargargs 也意味着 你不能传递任何参数,所以:
static void stuff(int... arg)
和
static void stuff(Integer... arg)
两者都可以在不带参数的情况下被调用...所以这将在 JVM 应该调用什么方法方面产生一些冲突
考虑以下对 stuff()
的两个假设调用:
int a = 14;
Integer b = new Integer(14);
stuff(a, b);
stuff(b, a);
编译器怎么知道应该在这里调用哪个方法?由于自动装箱规则,任一调用都可以引用任一重载方法。
更新:
我的回答在逻辑上是正确的,或者至少是在正确的轨道上,但是更正式的回答我们可以参考这个SO问题:
Why ambiguous error when using varargs overloading with primitive type and wrapper class?
这两个可变参数方法是在松散调用上下文中调用的。因此,编译器将尝试通过 JLS 15.12.2.5 Choosing the Most Specific Method 找到更具体的方法。但是,由于 int
和 Integer
都不是彼此的子类型,因此编译器会抛出错误。