Java可变参数

在jdk5之前,可能我们要通过这样的方式来实现可变参数的方法:

package www.com.thinkInJava.initializationCleanup;

public class VarArgs {
    static void printArray(Object[] args) {
        for(Object obj : args) {
            System.out.print(obj + " ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        printArray(new Object[]{new Integer(23), 23.2f, "sdfdsf", new Double(23.234), new A()});
    }
    
}

class A{}

通过Object[]数组来实现。

输出如下:

但在jdk5之后,Java终于有可变参数这个特征了。

语法类似于static void printArray(Object... args)

package www.com.thinkInJava.initializationCleanup;

public class VarArgs {
    static void printArray(Object...args) {
        for(Object obj : args) {
            System.out.print(obj + " ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        printArray(new Integer(32), 23.f, "sfsdf", new String("helosdfakl"), 234, new A());
        printArray((Object[])new Integer[]{12, 23, 345, 456, new Integer(666)});
        printArray();
    }
    
}

class A{}

输出如下:

main函数里的第一句调用可见,这个可变参数的原理应该类似于我们之前的Object[]的方法,因为我们传进去的是普通的不同的参数,而却可以用array的foreach来遍历元素,说明应该是自动将一系列元素转换成了数组;

main函数的第二句调用可见,还可以直接传一个数组Object的array进去。(这里我们将Integer引用的数组转换成了Object的,同时数组的定义里面也用了autoboxing,即把普通的int自动转换成对应的Integer对象。)

main函数的第三句调用可见,对于可变参数的方法,可以什么都不传过去。

下面一个例子证明了,可变参数确实是把参数转换成了数组的形式:

package www.com.thinkInJava.initializationCleanup;

public class VarargType {
    static void f(Character... args) {
        System.out.print(args.getClass());
        System.out.println(" length " + args.length);
    }

    static void g(int... args) {
        System.out.print(args.getClass());
        System.out.println(" length " + args.length);
    }
    
    public static void main(String[] args) {
        f('a');
        f();
        g(1);
        g();
        System.out.println("int[]: " + new int[0].getClass());
    }
}

输出:

这里,class的描述,有个“[”开头,表明这个class是个数组,然后中括号后面紧跟着的就是这个数组的数据类型,像这里紧跟着的I表明这是个基本数据类型int的数组。

main函数里面最后的一行代码证明了这个过程,直接输出了一个int数组的getClass,输出和上面的一样,证明可变参数确实是把元素转换成数组。

方法的重载overload也是可以用可变参数的,但可能会使方法变得很复杂,建议小心使用,这里也给个例子:

package www.com.thinkInJava.initializationCleanup;

public class OverloadingVarargs {
    static void f(Character... args) {
        System.out.print("first");
        for (Character c : args)
            System.out.print(" " + c);
        System.out.println();
    }

    static void f(Integer... args) {
        System.out.print("second");
        for (Integer i : args)
            System.out.print(" " + i);
        System.out.println();
    }

    static void f(Long... args) {
        System.out.println("third");
    }

    public static void main(String[] args) {
        f('a', 'b', 'c');
        f(1);
        f(2, 1);
        f(0);
        f(0L);
        // ! f(); // Won’t compile -- ambiguous
    }

}

输出结果:

这里看到,不能调用没有参数的f()了,因为编译器无法辨别是哪个方法。这个无参数的方法调用连编译都无法通过。

原文地址:https://www.cnblogs.com/wangshen31/p/9406466.html