可以提供参数数量可变的方法(有时这些方法被称为“变参”(varags)方法)。

前面已经看到过这样的一个方法:printf。例如,下面的方法调用:
System.out.printf("%d", 1);
System.out.printf("%d %s", 1, "widgets");
这两条语句都调用了同一个方法,不过一个调用有两个参数,另一个调用有三个参数。
printf 方法是这样定义的:

public class PrintStream
{
    public PrintStream printf(String fmt, Object... args) { 
        return format(fmt, args); 
    }
}

这里的省略号 ... 是 Java 代码的一部分,它表明这个方法可以接收任意数量的对象(除 fmt 参数之外)。

实际上,printf 方法接收两个参数,一个是格式字符串,另一个是 Object[] 数组,其中保存着所有的其他参数(如果调用者提供的是整数或者其他基本类型的值,会把它们自动装箱为对象)。现在不可避免地要扫描 fmt 字符串,并将第 i 个格式说明符与 args[i] 的值匹配起来。

换句话说,对于 printf 的实现者来说,Object... 参数类型与 Object[] 完全一样。

编译器需要转换每个 printf 调用,将参数绑定到数组中,并在必要的时候进行自动装箱:
System.out.printf("%d %s", new Object[] { new Integer(n), "widgets" } );

可以自定义有可变参数的方法,可以为参数指定任意类型,甚至是基本类型。下面是一个计算若干数值中最大值函数的例子:

public static double max(double... values) {
    double largest = Double.NEGATIVE_INFINITY;
    for(double v : values) {
        if(v > largest) {
            largest = v;
        }
    }
    return largest;
}

可以这样调用这个方法:
double m = max(3.1, 40.4, -5);

注释: 允许将数组作为最后一个参数传递给有可变参数的方法。 例如:
System.out.printf("%d %s", new Object[] { new Integer(l), "widgets" });
因此,如果一个已有方法的最后一个参数是数组,可以把它重新定义为有可变参数的方法,而不会破坏任意已有的代码。例如,Java 5 中就采用这种方式增强了 MessageFormat.format。如果愿意,甚至可以将 main 方法声明为以下形式:
public static void main(String... args)