Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Герберт Шилдт. Java 2, v5.0 (Tiger). Новые возм...doc
Скачиваний:
5
Добавлен:
01.03.2025
Размер:
1.21 Mб
Скачать

Глава 5 Аргументы переменной длины

Версия Java 2 5.0 содержит новое средство, упрощающее создание методов, которым приходится принимать разное количество аргументов. Это средство названо varags, сокращение от английского "variable-length arguments" (аргументы переменной длины). Метод, принимающий разное число аргументов, называется методом с переменным количеством аргументов (variable-arity).

Ситуации, требующие передачи методу переменного числа аргументов, не так уж редки. Например, метод, открывающий интернет-соединение, может принимать имя пользователя, пароль, имя файла, протокол и так далее, но при отсутствии некоторых из этих аргументов способен заменить их значениями по умолчанию. В этом случае было бы удобно передавать только те аргументы, значения которых отличаются от значений по умолчанию. Другим примером может служить новый метод printf(), входящий в библиотеку ввода/вывода языка Java. Как Вы увидите в главе 9, он принимает переменное число аргументов, которые форматируются, а затем выводятся.

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

До выхода версии Java 2 5.0 переменное количество аргументов обрабатывалось двумя способами, ни один из которых нельзя назвать удобным. Во-первых, если максимальное число аргументов не велико и известно, можно было создать перегружаемые версии метода, по одной на каждый вариант списка передаваемых в метод аргументов. Хотя этот способ работает и подходит для некоторых случаев, он применим лишь к узкому классу задач.

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

Листинг 5.1. Применение массива для передачи разного количества аргументов методу

// Use an array to pass a variable number of

// arguments to a method. This is the old-style

// approach to variable-length arguments.

class PassArray {

static void vaTest(int v[]) {

System.out.print("Number of args: " + v.length +

" Contents: ");

for(int x : v)

System.out.print(x + " ");

System.out.println();

}

public static void main(String args[])

{

// Notice how an array must be created to

// hold the arguments.

int n1[] = { 10 };

int n2[] = { 1, 2, 3 };

int n3[] = { };

vaTest(n1); // 1 arg

vaTest(n2); // 3 args

vaTest(n3); // no args

}

}

Далее приведен вывод результатов работы программы из листинга 5.1:

Number of args: 1 Contents: 10

Number of args: 3Contents: 1 2 3

Number of args: 0 Contents:

В листинге 5.1 методу vaTest() аргументы передаются в массиве v. Этот устаревший подход, тем не менее, позволяет методу vaTest() принимать произвольное число аргументов. Но при этом необходимо вручную упаковать аргументы в массив перед вызовом метода vaTest(). Кроме того, что формировать массив для каждого вызова vaTest() утомительно, это действие может быть источником ошибок. Новое средство создания списков с произвольным количеством аргументов предлагает более простой и удобный способ.

Аргумент переменной длины (содержащий переменное число аргументов) задается тремя точками (...). В следующей строке приведен пример описания метода vaTest(), использующего аргумент переменной длины:

static void vaTest (int...v) {

Эта синтаксическая запись сообщает компилятору, что vaTest() может вызываться без параметров, с одним или несколькими параметрами. В результате переменная v, аргумент переменной длины, неявно объявляется массивом типа int[ ]. Таким образом, в теле метода vaTest() для доступа к v используется нормальный синтаксис работы с массивом. В листинге 5.2 приведен вариант программы из листинга 5.1, но с применением средства формирования списка с переменным числом аргументов.

Листинг 5.2. Демонстрация средства формирования списка с переменным числом элементов

// vaTest() now uses a vararg.

static void vaTest(int ... v) {

System.out.print("Number of args: " + v.length +

" Contents: ");

for(int x : v)

System.out.print(x + " ");

System.out.println();

}

public static void main(String args[])

{

// Notice how vaTest() can be called with a

// variable number of arguments.

vaTest(10); // 1 arg

vaTest(1, 2, 3); // 3 args

vaTest(); // no args

}

}

Вывод у программы из листинга 5.2 такой же, как у примера из листинга 5.1.

В приведенной программе следует обратить внимание на два момента. Во-первых, как уже упоминалось, внутри метода vaTest() аргумент переменной длины, v, обрабатывается как массив, потому что v и есть массив. Символьная комбинация ... сообщает компилятору о том, что будет использоваться переменное число аргументов, и что эти аргументы будут храниться в массиве, ссылка на который содержится в переменной v. Во-вторых, в методе main() метод vaTest() вызывается с разным числом аргументов, включая полное их отсутствие. Аргументы автоматически помещаются в массив и передаются переменной v. В случае отсутствия аргументов длина массива равна 0.

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

int doIt (int a, int b, double с, int...vals) {

В приведенном примере первые три аргумента, используемые при вызове метода doIt (), соответствуют первым трем параметрам. Любые оставшиеся аргументы будут передаваться в переменной vals.

Запомните: параметр переменной длины (т. е. содержащий произвольное число аргументов) должен быть последним в списке параметров метода. В следующей строке приведен пример некорректного объявления:

Int doIt (int a, int b, double c,int-vals,Boolean stopFlag){//Ошибка!

В приведенной строке делается попытка объявить обычный параметр после параметра переменной длины, что недопустимо.

Следует знать еще об одном ограничении: в списке параметров метода может быть только один параметр переменной длины. В следующей строке тоже приведено неправильное объявление:

int doIt {int a, int b, double с, int…vals, double…morevals) { // Ошибка!

Попытка указать второй параметр переменной длины также недопустима.

В листинге 5.3 приведена переработанная версия метода vaTest(), которая принимает обычный аргумент и аргумент переменной длины.

Листинг 5.3. Использование аргумента переменной длины и обычного аргумента

class VarArgs2 {

// Here, msg is a normal parameter and v is a

// varargs parameter.

static void vaTest(String msg, int ... v) {

System.out.print(msg + v.length +

" Contents: ");

for(int x : v)

System.out.print(x + " ");

System.out.println();

}

public static void main(String args[])

{

vaTest("One vararg: ", 10);

vaTest("Three varargs: ", 1, 2, 3);

vaTest("No varargs: ");

}

}

Далее приведен вывод результатов работы программы из листинга 5.3:

One vararg: I Contents: 10

Three varargs: 3 Contents: 1 2 3

No varargs: 0 contents: