方法重载中的原始vararg参数

时间:2017-03-23 13:41:10

标签: java arrays overloading variadic-functions primitive

原始人再次参与其中,破坏了规则,我之前学到过。不是技术原始,而是由它们组成。

我了解到,只要没有比rest更具体的方法,就会发生编译时错误。

public static void caller(){
    z5();  // Error. Neither Integer, nor String is more specific
    z5(null);  // Error for the same reason
}
public static void z5(Integer...integers){
    System.out.println("Integer z5 called");
}
public static void z5(String...strings){
    System.out.println("String z5 called");
}

现在有了原始的图片。

public static void caller(){
    z1(null);  // Error cuz [I, [J, [F all are subclass of Object.
    z1();  // SURPRISINGLY works and calls the int one. WHY?
}
public static void z1(int...integers){
    System.out.println("int z1 called");
}
public static void z1(long...longs){
    System.out.println("long z1 called");
}
public static void z1(float...floats){
    System.out.println("float z1 called");
}

此处发生预期的编译时错误。

public static void caller(){
    z1(null);  // Error
    z1();  // Error
}
public static void z1(int...integers){
    System.out.println("int z1 called");
}
public static void z1(boolean...bools){
    System.out.println("bool z1 called");
}

现在我的问题是,int [],float []或任何基元数组都不是原始类型那么为什么它们的处理方式与其他引用类型不同?

- UPDATE -

@john16384您认为我没有看到您的“可能重复”Varargs in method overloading in Java

那里的最佳答案是你无法将var-args与扩展或装箱结合起来。除了我忘记提及,OP的代码发布在那里,在我的jdk 7上工作正常。

对于(int ... is)& (浮动... fs)但不适用于(整数...是)& (Float ... fs)而不是(int ... is)&的(布尔...布尔)

1 个答案:

答案 0 :(得分:1)

当多种方法适用时,从JLS引用有关varargs调用的信息:

  

15.12.2.5。选择最具体的方法

     

如果多个成员方法都可访问且适用于a   方法调用,有必要选择一个提供   运行时方法调度的描述符。 Java编程   language使用选择最具体方法的规则。

     

非正式的直觉是一种方法更具体   如果可以传递第一个方法处理的任何调用,则为另一个   没有编译时错误的另一个。在诸如此类的情况下   显式类型化的lambda表达式参数(第15.27.1节)或变量   arity调用(§15.12.2.4),允许一些灵活性适应   一个签名到另一个。

这里的重要部分是如何定义方法更具体。它基本上表示int...long...更具体,因为您传递给第一个方法的任何值也可以传递给第二个方法。

这也适用于不传递参数的情况。 int...将是最具体的(甚至会byte...更具体!)。

public static void main(String[] args) {
    bla();
}

private static void bla(long... x) {}
private static void bla(int... x) {}
private static void bla(short... x) {}
private static void bla(byte... x) {}   // <-- calls this one

在创建重载boolean...时出现错误的原因是它现在是一个可以调用的人,并且编译器在到达必须选择最具体方法的点之前停止。< / p>