|
Используете методы с переменным числом аргументов? Забудьте о создании массивов параметров вручную - используйте varargs!
В старых версиях JDK, вызов метода, который принимает
произвольное число параметров, был сопряжен с написанием вспомогательного кода, который создавал массив и
помещал в него фактические параметры.
В качестве примера, вот как приходилось использовать класс MessageFormat для форматирования
сообщения:
Object[] arguments = {
new Integer(7),
new Date(),
"a disturbance in the Force"
};
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet "
+ "{0,number,integer}.", arguments);
Такой подход работает и в новых версиях JDK, но начиная с JDK 5.0 того же результата можно достичь гораздо проще. Как? Использовать синтаксис для работы со списками параметров переменной
длины (varargs). Обратите внимание, что это только синтаксис и его использование не влечет появление несовместимости с существующим API.
Используя новый синтаксис,
метод MessageFormat.format теперь может быть описан следующим
образом:
public static String format(String pattern, Object... arguments);
Многоточие после типа последнего параметра обозначает, что его можно
передать как массив или как последовательность аргументов. Обратите внимание, что такой синтаксис можно использовать только для последнего аргумента.
С использованием
нового описания метода MessageFormat.format() при помощи списков аргументов, вызов
метода, приведенный выше, можно заменить следующим, куда более коротким
и приятным выражением:
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet "
+ "{0,number,integer}.",
7, new Date(), "a disturbance in the Force");
За счет использования таких функциональных возможностей, как
автоматическое приведение типов (autoboxing) и списки
параметров (varargs),
можно достигнуть значительного упрощения кода. Например, рассмотрим следующюю программу, которая использует reflection
API:
public class Test {
public static void main(String[] args) {
int passed = 0;
int failed = 0;
for (String className : args) {
try {
Class c = Class.forName(className);
c.getMethod("test").invoke(c.newInstance());
passed++;
} catch (Exception ex) {
System.out.printf("%s failed: %s%n", className, ex);
failed++;
}
}
System.out.printf("passed=%d; failed=%d%n", passed, failed);
}
}
Эта маленькая программа представляет собой небольшой, но вполне полноценный каркас для выполнения тестов. Она принимает список имен классов из
командной строки. Для каждого класса создается его экземпляр с
использованием конструктора без параметров, а также вызывается метод
test без параметров. Если при создании сущности класса или при вызове
метода возникает исключение, считается, что тест провалился. Программа
выводит на печать сообщение о каждом падении теста, сопровождая его кратким
описанием результатов. Создание сущности и вызов методов при помощи reflection не требуют больше явного создания массива, поскольку методы
getMethod и invoke принимают произвольное число аргументов. Программа
также использует другую новинку - возможность печати с помощью метода printf(), основанную на
использовании списков параметров. Код выглядит гораздо более лаконичным и понятным благодаря использованию списков параметров.
В каких случаях следует использовать списки параметров переменной длинны? Если вы пользуютесь готовым API, то безусловно вам стоит использовать списки параметров всегда, когда есть такая возможность. В стандартном JDK API, применение списков параметров переменной длины значительно повысило удобство использования reflection API, API для форматирования сообщений и printf.
Как архитектор
программного интерфейса все же не стоит злоупотреблять применением списков переменной длины. Используйте их тогда, когда в этом есть
явная необходимость. Один из подводных камней - перегрузка методов с переменным числом аргументов. Избегайте ее, или разработчикам будет довольно сложно понять,
какой из перегруженных методов был вызван
Перевод: Ксения Ш., Дмитриев А.
Оригинал
. |