我可以将数组作为参数传递给 Java 中具有可变参数的方法吗?
我希望能够创建一个如下函数:
class A {
private String extraVar;
public String myFormat(String format, Object ... args){
return String.format(format, extraVar, args);
}
}
这里的问题是 args
在方法 myFormat
中被视为 Object[]
,因此是 String.format
的单个参数,而我希望将 args
中的每个 Object
作为新参数传递。由于 String.format
也是一个带有可变参数的方法,所以这应该是可能的。
如果这是不可能的,是否有类似 String.format(String format, Object[] args) 的方法?在这种情况下,我可以使用新数组将 extraVar
附加到 args
并将其传递给该方法。
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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的,
T...
只是T[]
的语法糖。JLS 8.4.1 格式参数< /a>
下面是一个例子来说明:
是的,上面的
main
方法是有效的,因为String...
只是String[]
。此外,由于数组是协变的,String[]
是Object[]
,因此您也可以以任何一种方式调用ezFormat(args)
。另请参阅
#1: 传递
null
可变参数的解析是相当复杂的,有时它会做一些让你惊讶的事情。
考虑这个例子:
由于可变参数的解析方式,最后一个语句使用
objs = null
进行调用,这当然会导致NullPointerException
与objs.length
>。如果您想为 varargs 参数提供一个null
参数,您可以执行以下任一操作:相关问题
以下是人们在处理 varargs 时提出的一些问题的示例:
Vararg 陷阱 #2:添加额外参数
正如您所发现的出来,以下内容不起作用:
由于可变参数的工作方式,
ezFormat
实际上获取 2 个参数,第一个是String[]
,第二个是字符串
。如果您将数组传递给 varargs,并且希望其元素被识别为单独的参数,并且还需要添加额外的参数,那么您别无选择,只能创建另一个数组容纳额外的元素。以下是一些有用的辅助方法:
现在您可以执行以下操作:
Varargs 陷阱#3:传递基元数组
它不起作用:
Varargs 仅适用于引用类型。自动装箱不适用于基元数组。以下作品:
Yes, a
T...
is only a syntactic sugar for aT[]
.JLS 8.4.1 Format parameters
Here's an example to illustrate:
And yes, the above
main
method is valid, because again,String...
is justString[]
. Also, because arrays are covariant, aString[]
is anObject[]
, so you can also callezFormat(args)
either way.See also
Varargs gotchas #1: passing
null
How varargs are resolved is quite complicated, and sometimes it does things that may surprise you.
Consider this example:
Due to how varargs are resolved, the last statement invokes with
objs = null
, which of course would causeNullPointerException
withobjs.length
. If you want to give onenull
argument to a varargs parameter, you can do either of the following:Related questions
The following is a sample of some of the questions people have asked when dealing with varargs:
Vararg gotchas #2: adding extra arguments
As you've found out, the following doesn't "work":
Because of the way varargs work,
ezFormat
actually gets 2 arguments, the first being aString[]
, the second being aString
. 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.Here are some useful helper methods:
Now you can do the following:
Varargs gotchas #3: passing an array of primitives
It doesn't "work":
Varargs only works with reference types. Autoboxing does not apply to array of primitives. The following works:
可变参数方法的基础类型
function(Object... args)
是函数(Object[] args)
。 Sun 以这种方式添加可变参数以保持向后兼容性。因此,您应该能够在
args
前面添加extraVar
并调用String.format(format, args)
。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
toargs
and callString.format(format, args)
.传递一个数组是可以的 - 事实上它相当于相同的东西
,
它只是语法糖 - 编译器将第一个转换为第二个,因为底层方法需要 vararg 参数。
请参阅
It's ok to pass an array - in fact it amounts to the same thing
is the same as
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.
See
jasonmp85 关于将不同的数组传递给 String.format 的说法是正确的。数组的大小一旦构造就无法更改,因此您必须传递一个新数组而不是修改现有数组。
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.我有同样的问题。
然后将 obj 作为 varargs 参数传递。
它起作用了。
I was having same issue.
And then passed the obj as varargs argument.
It worked.
除了 @genelubricant 的#2 - 如果只读就足够了,并且如果您想付出一些额外的努力来获得
List
的一些便利 - 不一定需要复制数组并包装它,加上在访问时在任意索引处注入所需的额外值,可以这样实现:In addition to #2 of @genelubricant - in case read-only is enough and if you want to swap a little extra effort for gaining some of the conveniences of a
List
- copying the array is not necessarily required and wrapping it, plus injecting the desired extra value at an arbitrary index at access time, can be achieved like this: