Java произвольное количество аргументов

Varargs

In past releases, a method that took an arbitrary number of values required you to create an array and put the values into the array prior to invoking the method. For example, here is how one used the MessageFormat class to format a message:

Object[] arguments = < new Integer(7), new Date(), "a disturbance in the Force" >; String result = MessageFormat.format( "At on , there was on planet " + ".", arguments);

It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process. Furthermore, it is upward compatible with preexisting APIs. So, for example, the MessageFormat.format method now has this declaration:

public static String format(String pattern, Object. arguments);

The three periods after the final parameter’s type indicate that the final argument may be passed as an array or as a sequence of arguments. Varargs can be used only in the final argument position. Given the new varargs declaration for MessageFormat.format , the above invocation may be replaced by the following shorter and sweeter invocation:

String result = MessageFormat.format( "At on , there was on planet " + ".", 7, new Date(), "a disturbance in the Force");

There is a strong synergy between autoboxing and varargs, which is illustrated in the following program using reflection:

// Simple test framework 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); > >

This little program is a complete, if minimal, test framework. It takes a list of class names on the command line. For each class name, it instantiates the class using its parameterless constructor and invokes a parameterless method called test. If the instantiation or invocation throws an exception, the test is deemed to have failed. The program prints each failure, followed by a summary of the test results. The reflective instantiation and invocation no longer require explicit array creation, because the getMethod and invoke methods accept a variable argument list. The program also uses the new printf facility, which relies on varargs. The program reads much more naturally than it would without varargs.

Читайте также:  Python tkinter directory select

So when should you use varargs? As a client, you should take advantage of them whenever the API offers them. Important uses in core APIs include reflection, message formatting, and the new printf facility. As an API designer, you should use them sparingly, only when the benefit is truly compelling. Generally speaking, you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called.

Источник

Java произвольное количество аргументов

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

Varargs (Variable Arguments List, изменяющийся список аргументов) — это способ создания методов, которые могут принимать произвольное количество аргументов одного типа (от нуля и более). Данная возможность появилась в JDK 5.

В книге «Java. Эффективное программирование» Джошуа Блох пишет: «Использование переменного количества аргументов было разработано для метода printf и рефлексии». Также он называет varargs-методы, как variable arity, т. е. методы с переменной арностью (термин из математики, означающий количество передаваемых аргументов).

Метод printf (аналог одноименного метода из языка C), как и методы print и println, предназначен для вывода сообщений в консоль, но, в отличие от последних, позволяет применять к ним форматирование. Реализации данных методов находятся в пакете java.io в классе PrintStream, но их мы знаем как методы, вызываемые в конструкции System.out.*

 public PrintStream printf(String format, Object. args)
  • String format — выводимое на консоль сообщение, включающее параметры форматирования (дескрипторы)
  • Object… args — произвольное количество значений форматируемых переменных

В целом, можно сказать, что инструкции из String format применяются для форматирования аргументов Object… args.

Запись вида Object… args и есть varargs. Существуют, конечно, и другие способы написания: Object …args или даже Object … args, но они не распространены, и их использовать не стоит. При этом три точки после типа указывают, что метод в качестве аргумента может принимать как массив, так и любую последовательность аргументов, записанных через запятую, которая все равно преобразуется в одномерный массив.

«Под капотом» компилятор на уровне байт-кода неявно заменяет переданную последовательность массивом. По смыслу это равносильно следующей записи:

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

 System.out.printf("Hello"); System.out.printf("Player %s attempts: ", player.getName()); System.out.printf("%5s %5s %n", "Dec", "Char"); System.out.printf("Число %,d содержит %d %s количество единиц%n", a, b, c); 

Как видно из примера, printf может принимать разное количество аргументов: в нашем случае от одного до четырех. Такая гибкость как раз и обеспечивается за счет конструкции Object… args (тип ожидаемых аргументов может быть любым, не обязательно Object).

  1. Использовать массив в качестве контейнера для передачи в метод разного количества аргументов (зачастую это громоздко):
 char[] arr = new char[4]; arr[0] = 'J'; arr[1] = 'a'; arr[2] = 'v'; arr[3] = 'a'; print(arr); void print(char[] arr) < // какой-то код >

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

 void start(Player p1) <> void start(Player p1, Player p2) <> void start(Player p1, Player p2, Player p3) <> void start(Player p1, Player p2, Player p3, Player p4) <> 

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

  • упрощение кода
  • уменьшение многословности языка
  • облегчение работы программиста
  • удобство

Пусть необходимо реализовать метод, который принимает последовательность аргументов типа String и отображает их в консоли. Для демонстрации воспользуемся методом main, используя в качестве принимаемого аргумента varargs. При этом следует отметить, что String[] и String… являются синонимами.

 > java VarargsTest.java My name is Max! Длина массива (количество аргументов) = 4 My name is Max! 

Стоит отметить, что если запустить программу без указания дополнительных аргументов, то массив все равно будет создан и передан в метод, при этом его размер будет равен 0. Попробуйте самостоятельно в этом убедиться.

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

 1. public void foo1(int. nums, String values) <> 2. public void foo2(String. values, int. nums) <> 3. public void foo3(String[] values, . int nums) <> 
  1. varargs не является последним
  2. два varargs не допускаются в одном методе
  3. … необходимо размещать после типа, а не до него
 public int howMany(boolean b, boolean. b2)
 A. howMany(); B. howMany(true); C. howMany(true, true); D. howMany(true, true, true); E. howMany(true, ); F. howMany(true, new boolean[2]); 
  • Вариант A не cкомпилируется, потому что в методе не передается хотя бы начальный параметр (boolean b). Тут действует то правило, когда varargs может быть равен 0, но все остальные аргументы обязательно должны быть переданы
  • Вариант B и C правильные, т. к. первый вызов соответствует правилу из предыдущего пункта, а во втором создается массив размером 1
  • Варианты D и F правильные, т. к. передают нужное количество аргументов: начальный и еще два для преобразования в массив varargs размером 2
  • Вариант E не скомпилируется, потому что неверно объявляется массив: должно быть new boolean[]
  • Вариант F верный, т. к. передает начальный параметр и массив размером 2 (массивы и varargs являются синонимами)

Давайте взглянем на методы of из интерфейса List. Не переживайте, что не знаете, что такое интерфейс, а тем более — не знакомы с List. Это сейчас не самая важная информация. Если хотите, можете воспринимать List, как стандартный «класс» Java, который позволяет создавать динамический массив, умеющий увеличивать свой размер по мере необходимости (у обычного массива размер устанавливается один раз — в момент его создания). Все это вы изучите, когда придет время.

А на данный момент нас интересуют методы of интерфейса List. Как оказывается, этих методов много, от чего они, на первый взгляд, выглядят странно:

 of() of(E e1) of(E e1, E e2) of(E e1, E e2, E e3) of(E e1, E e2, E e3, E e4) of(E e1, E e2, E e3, E e4, E e5) of(E e1, E e2, E e3, E e4, E e5, E e6) of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) of(E. elements) 

Источник

Переменное число аргументов методов языка Java

Переменное число аргументов методов языка Java

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

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

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

До версии J2SE5 для поддержки списков аргументов переменной длины применя­лись два способа, ни один из которых не был особенно удобен.

Во-первых, если макси­мально возможное количество аргументов было невелико и заранее известно, то можно было создавать перегруженные версии метода — по одной для каждого способа его вы­зова. Очевидно, что такой подход применим лишь в отдельных случаях.

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

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

Такое решение было предложено в JDK 5. Новое средство, которое позволило изба­виться от явного формирования массива аргументов перед вызовом метода, получило название varargs (сокращение от variable-length arguments — список аргументов перемен­ной длины).

Соответствующие методы называют методами с переменным числом аргу­ментов (другое название — методы переменной арности). В методах этого типа список параметров имеет не фиксированную, а переменную длину, что обеспечивает дополни­тельную гибкость, позволяя методам принимать произвольное число аргументов.

Пользуюсь случаем, хочу спросить аудиторию: работали ли вы когда-то с WordPress-ом? Очень нужен шаблон ThemeForest Motors, уж очень сильно он подойдет для одного моего проекта. Могу отблагодарить материально.

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

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

Источник

Оцените статью