Методы для работы с переменным количеством аргументов

Методы для работы с переменным количеством аргументов, позволяют принимать произвольное количество аргументов. До выхода JDK 5.0 для передачи методу произвольного числа аргументов, необходимо было использовать массив объектов. Более того, отсутствовала возможность использования списка аргументов с такими методами, как метод форматирования класса MessageFormat, или с новым методом JDK 5.0 printf класса PrintStream, для добавления дополнительных аргументов к строке форматирования. Старый способ использования списков аргументов описан в совете Using Variable Argument Lists от 4 февраля 2003 года.

В JDK 5.0 добавлен гибкий механизм работы с переменным количеством агрументов. Для изучения возможностей данного механизма, давайте рассмотрим версию метода printf класса PrintStream, используемую в JDK 5.0:

public PrintStream printf(String format,  Object... args)

Описание данного метода приводится в совете Formatting Output With the New Formatter, опубликованном в октябре 2004 года.

По умолчанию, первым аргументом данного метода является строка, заполненная символами, определяющими последующие аргументы. Многоточие во втором аргументе показывает, что он может быть представлен в виде массива или последовательности аргументов. Заметьте, что применение символа многоточия аналогично применению данного символа с языках С и С++ для определения списка аргументов.

Количество символов-заполнителей в строке форматирования задает число передаваемых аргументов. Например, строка форматирования: "Hello, %1s\nToday is %2$tB %2$te, %2$tY", требует наличия двух аргументов - первый строкового типа и второй типа дата. Ниже приводится пример использования данного метода:

import java.util.*;

public class Today {
 
public static void main(String args[]) {
   
System.out.printf("Hello, %1s%nToday is %2$tB %2$te, %2$tY%n", args[0],
       
new Date());
 
}
}

Если в качестве аргумента вы зададите имя, то результат выполнения данного примера будет следующим:

> java Today Ed
   Hello, Ed
   Today is October 18, 2005

Автоматическое преобразование типов позволяет вам передвать в качестве аргументов примитивные типы (как в следующем примере метода printf):

System.out.printf("Pi is approximately  %f", Math.PI, %n);

В данном примере аргумент Math.PI имеет тип double. Автоматическое преобразование типов переводит его в объект типа Double. (Подробное описание автоматического преобразования типов дается с совете Introduction to Autoboxing от 5 апреля 2005 года).

При создании собственных методов, принимающих переменное количество элементов, учтите, что только последний аргумент метода может принимать переменное количество элементов. Вы не можете задавать аргумент с переменным количеством элементов первым. Например, следующее определение метода является верным. В нем определяется метод принимающий один параметр, являющийся набором аргументов типа String:

private static void method1(String... args)

Параметр с перемнным числом аргументов не обязательно является единственным, передаваемым методу. Например, следующий метод принимает целочисленный агргумент, а затем пременное число аргументов.

private static void method2(int arg, Object... args)

При помещении вышеприведенных методов в класс, вы можете вызывать их, передавая переменное число аргументов:

method1("Hello", "World");
method1
(args);
method2
(12, 'a', "Hello", Math.PI, 1/3.0);
method2
(18, 94.0);

Во втором вызове метода есть небольшое отличие. Метод принимает аргумент String[], передаваемый из метода main(). Так как механизм работы с переменным количеством агрументов, неявно является способом для создания и передачи массивов, то с его помощью массив может быть передан напрямую. В данном случае компилятор передает неизмененный массив.

Ниже приводится класс MyArgs, реализующий два типа методов:

import java.util.*;

public class MyArgs {
 
public static void main(String args[]) {
   
method1("Hello", "World");
    method1
(args);
    method2
(12, 'a', "Hello", Math.PI, 1 / 3.0);
    method2
(18, 94.0);
 
}

 
private static void method1(String... args) {
   
System.out.println(Arrays.asList(args) + " // " + args.length);
 
}

 
private static void method2(int arg, Object... args) {
   
System.out.println(Arrays.asList(args) + " / " + arg);
 
}
}

Результат его выполнения буде следующим:

> java MyArgs x y z
   [Hello, World] // 2
   [x, y, z] // 3
   [a, Hello, 3.141592653589793, 0.3333333333333333] / 12
   [94.0] / 18

Класс MyArgs получает доступ к списку аргументов, передавая его методу Arrays.asList(). То есть, доступ к аргументам производится также как к элементам массива. В обычной практике вы скорее всего будете использовать расшириный цикл for для доступа к аргументам:

for (String arg: args) {
   
...
 
}

Данный код позволяет поочередно обрабатывать каждый элемент.

Как видите, механизм работы с переменным количеством агрументов позволяет вам легко сохдавать методы, принимающие пременное количество аргументов. Для более полного ознакомления с данным механизмом обращайтесь к статье Varargs .

Теги: java 5