Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重载var args_Java_Overloading_Variadic Functions - Fatal编程技术网

Java 重载var args

Java 重载var args,java,overloading,variadic-functions,Java,Overloading,Variadic Functions,谁能解释为什么第一种方法比第二种更可取 我知道重载的规则(除了首先编译器找到合适的参数) 加宽 自动装箱 变量args 代码: 控制台:对象…Java中的方法解析规则要求在尝试匹配这些功能之前,在不使用自动(取消)装箱和变量arity的情况下尝试匹配。这确保了源代码与这些功能之前的语言版本的兼容性 JLS(§15.12.2)中描述了过载解决的规则: 确定适用性的过程从确定潜在的 适用方法(§15.12.2.1) 该过程的其余部分分为三个阶段,以确保与 JavaSE5.0之前的Java编程语言版本

谁能解释为什么第一种方法比第二种更可取

我知道重载的规则(除了首先编译器找到合适的参数)

  • 加宽
  • 自动装箱
  • 变量args
  • 代码:


    控制台
    对象…

    Java中的方法解析规则要求在尝试匹配这些功能之前,在不使用自动(取消)装箱和变量arity的情况下尝试匹配。这确保了源代码与这些功能之前的语言版本的兼容性

    JLS(§15.12.2)中描述了过载解决的规则:

    确定适用性的过程从确定潜在的 适用方法(§15.12.2.1)

    该过程的其余部分分为三个阶段,以确保与 JavaSE5.0之前的Java编程语言版本。这些阶段是:

  • 第一阶段(§15.12.2.2)在不允许的情况下执行过载解决 装箱或取消装箱转换,或使用变量arity方法调用。 如果在此阶段未找到适用的方法,则继续处理 进入第二阶段。 这保证了任何在Java编程语言中有效的调用 在JavaSE5.0之前,由于引入了 变量算术方法、隐式装箱和/或取消装箱。但是, 可变算术方法(§8.4.1)可以改变为给定方法选择的方法 方法调用表达式,因为变量arity方法被视为固定的 在第一阶段中采用了算术方法。例如,在一个类中声明m(对象…) 已声明m(对象)导致不再为某些对象选择m(对象) 调用表达式(例如m(null)),因为m(Object[])更具体

  • 第二阶段(§15.12.2.3)在允许 装箱和拆箱,但仍然禁止使用变量算术方法 调用。如果在此阶段未找到适用的方法,则处理 继续到第三阶段。 这确保了永远不会通过变量arity方法调用来选择方法 如果它通过固定arity方法调用适用

  • 第三阶段(§15.12.2.4)允许过载与变量相结合 算术方法、装箱和拆箱

  • 在通用方法的情况下,决定方法是否适用将 (§8.4.4),要求确定类型参数。类型参数可能是 显式或隐式传递。如果它们是隐式传递的,则必须对其进行推断 (§15.12.2.7)从参数表达式的类型

    如果在三个阶段中的一个阶段确定了几种适用的方法 适用性测试,然后选择最具体的一个,如第节所述 §15.12.2.5


    在您的示例中,在步骤1中有两种候选方法:带有
    对象[]
    参数的方法和带有
    整数[]
    参数的方法。调用站点的参数类型为
    Integer[]
    。由于
    对象[]
    可从
    整数[]
    赋值,但
    整数[][]
    不可赋值,因此找到了一个适用的方法,重载解析在此停止。在这种情况下,永远不会达到第2步和第3步。

    Mike是正确的;有三个阶段,

    15.12.2.2。阶段1:通过子类型识别适用的匹配Arity方法

    15.12.2.3。阶段2:通过方法调用转换识别适用的匹配Arity方法

    15.12.2.4。阶段3:确定适用的变量算术方法

    show(Object[])
    在第一阶段被选中,但是
    show(Integer[])
    只能在第三阶段被选中

    如果第一个方法签名更改为
    show(Object[]…args)
    ,您将看到预期的结果

    如果第二个方法签名更改为
    show(Integer…args)
    ,您还将看到预期的结果。该方法也适用于第1阶段,它比
    show(Object…)


    如果我们有

    public static void show(Object ... args){
        System.out.println("Object ...");
    }
    
    static class IntArray{}
    
    public static void show(IntArray ... args){
        System.out.println("IntArray ...");
    }
    
    show(new IntArray());
    
    它将在阵列中打印所需的
    。此处
    IntArray
    不是
    对象[]
    的子类型



    这太令人困惑了。程序员通常不知道这些阶段;他们考虑所有适用的方法,以及其中最具体的方法。如果规范也这样做,可能会更好。

    您的var arg为
    Integer[]
    。所以是多个数组,而不是多个整数。Var-arg Integer[]。。。args可以接受整数[],为什么不这样做?我认为这比用对象调用show更明显。。。params.@SotiriosDelimanolis“多个”数组表示0个或多个数组。单个
    Integer[]
    对于担任不同角色的
    Integer[].
    Integer…
    都是可以接受的。
    public static void show(Object ... args){
        System.out.println("Object ...");
    }
    
    static class IntArray{}
    
    public static void show(IntArray ... args){
        System.out.println("IntArray ...");
    }
    
    show(new IntArray());