我可以将数组作为参数传递给 Java 中带有可变参数的方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2925153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I pass an array as arguments to a method with variable arguments in Java?
提问by user362382
I'd like to be able to create a function like:
我希望能够创建一个函数,如:
class A {
private String extraVar;
public String myFormat(String format, Object ... args){
return String.format(format, extraVar, args);
}
}
The problem here is that args
is treated as Object[]
in the method myFormat
, and thus is a single argument to String.format
, while I'd like every single Object
in args
to be passed as a new argument. Since String.format
is also a method with variable arguments, this should be possible.
这里的问题是在 method中args
被视为,因此是 的单个参数,而我希望每个in都作为新参数传递。由于也是一个带有可变参数的方法,这应该是可能的。Object[]
myFormat
String.format
Object
args
String.format
If this is not possible, is there a method like String.format(String format, Object[] args)
? In that case I could prepend extraVar
to args
using a new array and pass it to that method.
如果这是不可能的,是否有类似的方法String.format(String format, Object[] args)
?在这种情况下,我可以在前面加上extraVar
到args
使用新的数组,并把它传递给该方法。
采纳答案by jasonmp85
The underlying type of a variadic method function(Object... args)
isfunction(Object[] args)
. Sun added varargs in this manner to preserve backwards compatibility.
可变参数方法的基础类型function(Object... args)
是function(Object[] args)
. Sun 以这种方式添加了可变参数以保持向后兼容性。
So you should just be able to prepend extraVar
to args
and call String.format(format, args)
.
所以,你应该只能够预先考虑extraVar
到args
和呼叫String.format(format, args)
。
回答by mdma
It's ok to pass an array - in fact it amounts to the same thing
传递一个数组是可以的 - 事实上它等同于同样的事情
String.format("%s %s", "hello", "world!");
is the same as
是相同的
String.format("%s %s", new Object[] { "hello", "world!"});
It's just syntactic sugar - the compiler converts the first one into the second, since the underlying method is expecting an array for the varargparameter.
这只是语法糖 - 编译器将第一个转换为第二个,因为底层方法需要一个用于vararg参数的数组。
See
看
回答by ebelisle
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.
jasonmp85 将不同的数组传递给String.format
. 数组的大小一旦构造就无法更改,因此您必须传递一个新数组而不是修改现有数组。
Object newArgs = new Object[args.length+1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = extraVar;
String.format(format, extraVar, args);
回答by polygenelubricants
Yes, a T...
is only a syntactic sugar for a T[]
.
是的, aT...
只是 a 的语法糖T[]
。
JLS 8.4.1 Format parameters
JLS 8.4.1 格式参数
The last formal parameter in a list is special; it may be a variable arityparameter, indicated by an elipsis following the type.
If the last formal parameter is a variable arity parameter of type
T
, it is considered to define a formal parameter of typeT[]
. The method is then a variable aritymethod. Otherwise, it is a fixed aritymethod. Invocations of a variable arity method may contain more actual argument expressions than formal parameters. All the actual argument expressions that do not correspond to the formal parameters preceding the variable arity parameter will be evaluated and the results stored into an array that will be passed to the method invocation.
列表中的最后一个形参是特殊的;它可能是一个可变的参数,由类型后面的省略号表示。
如果最后一个形参是 type 的可变元参数
T
,则认为定义了一个 type 的形参T[]
。该方法则是可变元方法。否则,它是一个固定的数量方法。可变参数方法的调用可能包含比形式参数更多的实际参数表达式。所有与可变参数前面的形参不对应的实参表达式都将被评估,并将结果存储到一个数组中,该数组将传递给方法调用。
Here's an example to illustrate:
这里有一个例子来说明:
public static String ezFormat(Object... args) {
String format = new String(new char[args.length])
.replace("static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!
", "[ %s ]");
return String.format(format, args);
}
public static void main(String... args) {
System.out.println(ezFormat("A", "B", "C"));
// prints "[ A ][ B ][ C ]"
}
And yes, the above main
method is valid, because again, String...
is just String[]
. Also, because arrays are covariant, a String[]
is an Object[]
, so you can also call ezFormat(args)
either way.
是的,上述main
方法是有效的,因为同样,String...
只是String[]
. 另外,因为数组是协变的, aString[]
是 an Object[]
,所以你也可以用ezFormat(args)
任何一种方式调用。
See also
也可以看看
Varargs gotchas #1: passing null
Varargs 陷阱 #1:通过 null
How varargs are resolved is quite complicated, and sometimes it does things that may surprise you.
varargs 的解析方式非常复杂,有时它会做一些让您感到惊讶的事情。
Consider this example:
考虑这个例子:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Due to how varargs are resolved, the last statement invokes with objs = null
, which of course would cause NullPointerException
with objs.length
. If you want to give one null
argument to a varargs parameter, you can do either of the following:
由于可变参数的解析方式,最后一条语句调用 with objs = null
,这当然会导致NullPointerException
with objs.length
。如果您想为null
varargs 参数提供一个参数,您可以执行以下任一操作:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Related questions
相关问题
The following is a sample of some of the questions people have asked when dealing with varargs:
以下是人们在处理可变参数时提出的一些问题的示例:
- bug with varargs and overloading?
- How to work with varargs and reflection
- Most specific method with matches of both fixed/variable arity (varargs)
Vararg gotchas #2: adding extra arguments
Vararg 陷阱 #2:添加额外的参数
As you've found out, the following doesn't "work":
正如您所发现的,以下内容不起作用:
static <T> T[] append(T[] arr, T lastElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
arr[N] = lastElement;
return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
System.arraycopy(arr, 0, arr, 1, N);
arr[0] = firstElement;
return arr;
}
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 arraythat accommodates the extra element.
由于可变参数的工作方式,ezFormat
实际上有 2 个参数,第一个是 a String[]
,第二个是 a String
。如果您将一个数组传递给 varargs,并且您希望其元素被识别为单独的参数,并且您还需要添加一个额外的参数,那么您别无选择,只能创建另一个容纳额外元素的数组。
Here are some useful helper methods:
以下是一些有用的辅助方法:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(append(myArgs, "Z")));
// prints "[ A ][ B ][ C ][ Z ]"
System.out.println(ezFormat(prepend(myArgs, "Z")));
// prints "[ Z ][ A ][ B ][ C ]"
Now you can do the following:
现在您可以执行以下操作:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs gotchas #3: passing an array of primitives
Varargs 陷阱 #3:传递原始数组
It doesn't "work":
它不“工作”:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"
Varargs only works with reference types. Autoboxing does not apply to array of primitives. The following works:
Varargs 仅适用于引用类型。自动装箱不适用于基元数组。以下工作:
String[] arr= new String[] { "A", "B", "C" };
Object obj = arr;
回答by Srijit Paul
I was having same issue.
我有同样的问题。
##代码##And then passed the obj as varargs argument. It worked.
然后将 obj 作为可变参数传递。有效。