Параметры переменной длины и неопределенность

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

// Аргументы переменной длины, перегрузка и неопределенность.
//Эта программа содержит ошибку, и ее компиляция
// будет невозможна!
class VarArgs4 {
static void vaTest(int ... v) {
System.out.print("vaTest (int ...): " + "Количество аргументов: " + v.length + " Содержимое: ");
for(int x : v)
System, out .print (x -f " ") ;
System.out.println() ;
}
static void vaTest(boolean . . . v) {
System.out.print("vaTest(boolean ...) " + "Количество аргументов: " + v.length + " Содержимое: ");
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 (); // Ошибка: неопределенность!
}
}

В этой программе перегрузка метода vaTest () выполняется вполне корректно. Однако ее компиляция будет невозможна из-за следующего вызова:

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

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

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

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

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

vaTest(1)

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

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




Rambler's Top100