Can I pass an array as arguments to a method with variable arguments in Java?
Могу ли я передать массив в качестве аргументов методу с переменными аргументами в Java?
Я хотел бы иметь возможность создать функцию типа:
classA { private String extraVar; public String myFormat(String format, Object ... args){ return String.format(format, extraVar, args); } }
Проблема здесь в том, что args обрабатывается как Object[] в методе myFormat и, следовательно, является единственным аргументом для String.format, в то время как я бы хотел, чтобы каждый отдельный Object в args передавался как новый аргумент. Поскольку String.format это также метод с переменными аргументами, это должно быть возможно.
Если это невозможно, есть ли такой метод, как String.format(String format, Object[] args)? В этом случае я мог бы добавить extraVar к args, используя новый массив, и передать его этому методу.
Переведено автоматически
Ответ 1
Да, a T... это всего лишь синтаксический сахар для a T[].
Последний формальный параметр в списке является специальным; это может быть параметр переменной арности, обозначаемый эллипсисом после типа.
Если последний формальный параметр является параметром переменной арности типа T, считается, что он определяет формальный параметр типа T[]. В таком случае метод является методом переменной арности. В противном случае это метод фиксированной арности. Вызовы метода переменной арности могут содержать больше фактических выражений аргументов, чем формальных параметров. Все фактические выражения аргументов, которые не соответствуют формальным параметрам, предшествующим параметру переменной arity, будут вычислены, а результаты сохранены в массиве, который будет передан при вызове метода.
Вот пример для иллюстрации:
publicstatic String ezFormat(Object... args) { Stringformat=newString(newchar[args.length]) .replace("\0", "[ %s ]"); return String.format(format, args); } publicstaticvoidmain(String... args) { System.out.println(ezFormat("A", "B", "C")); // prints "[ A ][ B ][ C ]" }
И да, приведенный выше main метод допустим, потому что, опять же, String... это просто String[]. Кроме того, поскольку массивы ковариантны, a String[] является an Object[], поэтому вы также можете вызывать ezFormat(args) любым способом.
count(null, null, null); // prints "3" count(null, null); // prints "2" count(null); // throws java.lang.NullPointerException!!!
Из-за того, как разрешаются переменные, последний оператор вызывает with objs = null, что, конечно, вызвало бы NullPointerException with objs.length. Если вы хотите предоставить один null аргумент параметру varargs, вы можете выполнить любое из следующих действий:
count(newObject[] { null }); // prints "1" count((Object) null); // prints "1"
Связанные вопросы
Ниже приведен пример некоторых вопросов, которые люди задавали при работе с varargs:
As you've found out, the following doesn't "work":
String[] myArgs = { "A", "B", "C" }; System.out.println(ezFormat(myArgs, "Z")); // prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Because of the way varargs work, ezFormat actually gets 2 arguments, the first being a String[], the second being a String. If you're passing an array to varargs, and you want its elements to be recognized as individual arguments, and you also need to add an extra argument, then you have no choice but to create another array that accommodates the extra element.
The underlying type of a variadic method function(Object... args)isfunction(Object[] args). Sun added varargs in this manner to preserve backwards compatibility.
So you should just be able to prepend extraVar to args and call String.format(format, args).
Ответ 3
It's ok to pass an array - in fact it amounts to the same thing
It's just syntactic sugar - the compiler converts the first one into the second, since the underlying method is expecting an array for the vararg parameter.
jasonmp85 is right about passing a different array to String.format. The size of an array can't be changed once constructed, so you'd have to pass a new array instead of modifying the existing one.