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

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

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

Листинг 5.4. Аргументы переменной длины и перегрузка метода

class VarArgs3 {

static void vaTest(int ... v) {

System.out.print("vaTest(int ...): " +

"Number of args: " + v.length +

" Contents: ");

for(int x : v)

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

System.out.println();

}

static void vaTest(boolean ... v) {

System.out.print("vaTest(boolean ...) " +

"Number of args: " + v.length +

" Contents: ");

for(boolean x : v)

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

System.out.println();

}

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

System.out.print("vaTest(String, int ...): " +

msg + v.length +

" Contents: ");

for(int x : v)

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

System.out.println();

}

public static void main(String args[])

{

vaTest(1, 2, 3);

vaTest("Testing: ", 10, 20);

vaTest(true, false, false);

vaTest(); // Ошибка: неоднозначность!

}

}

Далее приведен вывод, формируемый программой из листинга 5.4:

vaTest (int...) : Number of args: 3 Contents: 1 2 3

vaTest (String, int...) : Testing: 2 Contents: 10 20

vaTest (boolean...) : Number of args: 3 Contents: true false false

В листинге 5.4 показаны два варианта перегрузки метода, содержащего аргумент переменной длины. Первый вариант — vaTest (boolean...) — отличается от vaTest (int...) типом параметра переменной длины. Напоминаю, что символьная комбинация ... заставляет интерпретировать параметр как массив заданного типа. Таким образом, так же, как Вы можете перегружать методы при использовании разных типов элементов массива-параметра, Вы можете перегружать методы при использовании разных типов параметров переменной длины. В этом случае язык Java по различию типов определяет, какой из перегруженных методов вызвать.

Во втором варианте перегрузки метода — vaTest (String, int...) — в метод с параметром переменной длины добавлен обычный параметр. В этой ситуации язык Java анализирует число аргументов и их тип для того, чтобы определить какой вариант метода вызвать.

Аргументы переменной длины и неоднозначность

Несколько неожиданные ошибки могут возникнуть при перегрузке методов, принимающих аргументы переменной длины. Эти ошибки связаны с неопределенностью, поскольку можно создать неоднозначный вызов перегруженного метода, принимающего аргумент переменной длины. Рассмотрим программу, приведенную в листинге 5.5.

Листинг 5.5. Аргументы переменной длины, перегрузка и неоднозначность

// Эта программа содержит ошибку и

// не будет компилироваться

class VarArgs4 {

static void vaTest(int ... v) {

System.out.print("vaTest(int ...): " +

"Number of args: " + v.length +

" Contents: ");

for(int x : v)

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

System.out.println();

}

static void vaTest(boolean ... v) {

System.out.print("vaTest(boolean ...) " +

"Number of args: " + v.length +

" Contents: ");

for(boolean x : v)

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

System.out.println();

}

public static void main(String args[])

{

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

vaTest(true, false, false); // OK

vaTest(); // Error: Ambiguous!

}

}

В приведенном примере перегрузка метода vaTest() вполне корректна. Но программа не будет компилироваться из-за, приведенного в следующей строке.

vaTest(); // Ошибка: неоднозначность!

Поскольку аргумент переменной длины может быть пустым, приведенный вызов можно интерпретировать как вызов варианта vaTest(boolean ...) или варианта vaTest(int ...). Оба одинаково правомерны. Следовательно, вызов по сути неоднозначен.

Далее приведен еще один пример неоднозначности. Следующие варианты метода vaTest() изначально неоднозначны, хотя один из них принимает обычный параметр:

static void vaTest(int .. .v) { //...

static void vaTest(int n, int .. .v) { //...

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

vaTest(1)

Перевести этот вызов в вариант vaTest (int ...) с одним значением в аргументе переменной длины или в вариант vaTest(int, int ...) без аргумента переменной длины? Компилятор не может ответить на этот вопрос. Следовательно, возникшая ситуация неоднозначна.

Из-за ошибок неоднозначности, подобных приведенным ранее, иногда Вам следует отказаться от перегрузки и просто использовать два метода с разными именами. В некоторых случаях ошибки неоднозначности выявляют концептуальный изъян в Вашем коде, который можно исправить, тщательно подбирая решение.