В этой статье вы узнаете о varargs в Java с помощью примеров. Вы также узнаете, когда использовать varargs, а когда нет.
Что такое varargs в Java?
Предположим, вы создаете метод Java. Однако вы не уверены, сколько аргументов будет принимать ваш метод. Для решения этой проблемы в Java 1.5 были введены varargs.
Varargs - это краткое название переменных аргументов. В Java аргумент метода может принимать произвольное количество значений. Этот аргумент, который может принимать переменное количество значений, называется varargs.
Синтаксис для реализации varargs следующий:
accessModifier methodName (datatype… arg) (// тело метода)
Чтобы определить vararg, …
(три точки) используются в формальном параметре метода.
Метод, который принимает переменное количество аргументов, называется методом переменной арности или просто методом varargs.
Для начала посмотрим на пример без использования varargs:
class NoVararg ( public int sumNumber(int a, int b)( return a+b; ) public int sumNumber(int a, int b, int c)( return a+b+c; ) public static void main( String() args ) ( NoVararg obj = new NoVararg(); System.out.println(obj.sumNumber(1, 2)); System.out.println(obj.sumNumber(1, 2, 3)); ) )
Когда вы запустите эту программу, вывод будет:
3 6
Как вы можете ясно видеть, вам пришлось перегрузить sumNumber()
метод, чтобы он работал с 3 аргументами.
Что, если пользователь хочет сложить 5 чисел, 10 или 100?
С этим можно аккуратно справиться с помощью varargs. Давайте посмотрим на пример кода:
Пример: работа varargs
class VarargExample ( public int sumNumber(int… args)( System.out.println("argument length: " + args.length); int sum = 0; for(int x: args)( sum += x; ) return sum; ) public static void main( String() args ) ( VarargExample ex = new VarargExample(); int sum2 = ex.sumNumber(2, 4); System.out.println("sum2 = " + sum2); int sum3 = ex.sumNumber(1, 3, 5); System.out.println("sum3 = " + sum3); int sum4 = ex.sumNumber(1, 3, 5, 7); System.out.println("sum4 = " + sum4); ) )
Когда вы запустите программу, вывод будет:
длина аргумента: 2 сумма2 = 6 длина аргумента: 3 сумма3 = 9 длина аргумента: 4 сумма4 = 16
Здесь sumNumber()
метод возвращает сумму int
переданных ему параметров (не имеет значения количество переданных аргументов).
Как видите, в некоторых ситуациях varargs может быть действительно полезен. Однако, если вы уверены в количестве аргументов, переданных методу, вместо этого используйте перегрузку метода. Например, если вы уверены, что этот sumNumber()
метод будет использоваться только для вычисления суммы 2 или 3 аргументов, используйте перегрузку, как в первом примере.
Возьмем другой пример. Метод format (), определенный в библиотеке Java, принимает varargs. В JDK format()
метод определяется следующим образом:
публичный статический строковый формат (язык l, строковый формат, объект… args) (// тело)
Пример: метод format ()
class Company ( public static void main(String() args) ( String siteName = "programiz.com"; int empCount = 6; String type = "tutorial website"; System.out.println( String.format( "Site Name : %s, Emp Count: %d Type: %s", siteName, empCount, type ) ); ) )
Когда вы запустите программу, вывод будет:
Название сайта: programiz.com, Emp Count: 6 Тип: обучающий веб-сайт
Как varargs работает за сценой?
Рассмотрим следующий псевдокод:
public int sumNumber (int… nums) (// тело метода)
…
Синтаксис говорит компилятор Java , что метод может быть вызван с нулем или более аргументов. В результате переменная nums неявно объявляется как массив типа int( )
. Таким образом, внутри метода доступ к переменной nums осуществляется с использованием синтаксиса массива.
В случае отсутствия аргументов длина числа равна 0.
Перегрузка методов Varargs
Подобно обычным методам, вы можете перегрузить методы vararg.
Рекомендуемая литература: Перегрузка методов Java
Пример: перегрузка метода Varargs
class VarargOverload ( private void test(int… args)( int sum = 0; for (int i: args) ( sum += i; ) System.out.println("sum = " + sum); ) private void test(boolean p, String… args)( boolean negate = !p; System.out.println("negate = " + negate); System.out.println("args.length = "+ args.length); ) public static void main( String() args ) ( VarargOverload obj = new VarargOverload(); obj.test(1, 2, 3); obj.test(true, "hello", "world"); ) )
Когда вы запустите программу, вывод будет:
sum = 6 negate = false args.length = 2
В приведенной выше программе test()
метод перегружается за счет изменения количества принимаемых аргументов.
Что нужно помнить при использовании Varargs
Вот несколько вещей, которые вы должны помнить при работе с варгарами Java:
1. При определении сигнатуры метода всегда сохраняйте наконец-то varargs.
Аргумент переменной должен быть последним аргументом, переданным методу. Предположим, вы вызвали doSomething()
такой метод:
doSomething (1, 2, 3, 4);
И ваш doSomething()
метод определяется как:
// неверное объявление метода public void doSomething (int… nums, int p) (// тело метода)
В этом случае компилятор не может определить количество аргументов, переданных в nums.
Однако, если вы определяете свой метод как:
public void doSomething (int p, int… nums) (// тело метода)
Компилятор Java присваивает первый аргумент p, а остальные int
аргументы - nums.
2. Метод может иметь только один параметр varargs.
Например, это объявление метода неверно:
int doSomething (int p, float… floatNums, double… doubleNums) (// код)
Неоднозначность в перегрузке метода Вараргса
Давайте рассмотрим ваш перегруженный test()
метод следующим образом:
class Demo (static void test (int… vargs) (// тело метода) static void test (int n, int… vargs) (// тело метода))
В приведенной выше программе компилятор запутается, если вы попытаетесь вызвать test()
метод, даже если test()
методы перегружены и принимают различное количество аргументов.
Компилятор не знает, какой метод вызвать. Компилятор может подумать, что вы пытаетесь вызвать test(int… vargs)
с одним аргументом varargs. Кроме того, компилятор может подумать, что вы пытаетесь вызвать test(int n, int… vargs)
с аргументом, переданным первому параметру, с пустым вторым параметром.
Поскольку есть две возможности, это вызывает двусмысленность. Из-за этого иногда может потребоваться использовать два разных имени метода вместо перегрузки метода varargs.