在Java中有没有办法创建一个期望两个不同varargs的方法?我知道,对于相同的对象类型来说这是不可能的,因为编译器不知道从哪里开始或结束。但是为什么使用两种不同的Object类型也不可能呢?
例如:
public void doSomething(String... s, int... i){
//...
//...
}
有没有办法创建这样的方法?
谢谢!
在Java中有没有办法创建一个期望两个不同varargs的方法?我知道,对于相同的对象类型来说这是不可能的,因为编译器不知道从哪里开始或结束。但是为什么使用两种不同的Object类型也不可能呢?
例如:
public void doSomething(String... s, int... i){
//...
//...
}
有没有办法创建这样的方法?
谢谢!
只能接受一个可变参数,很抱歉。但使用asList()函数可以让它变得近乎方便:
public void myMethod(List<Integer> args1, List<Integer> args2) {
...
}
-----------
import static java.util.Arrays.asList;
myMethod(asList(1,2,3), asList(4,5,6));
myMethod(List args1, List args2)
在上面的示例中,可以无需转换即可正常工作。 - recInteger
)而不是<?>
,则不需要进行强制转换。 - DaoWenjava.util.List;
才能使其工作。奇怪的是,Eclipse 不会自动导入 java.util.Arrays.asList;
。以防对任何人有所帮助,我想指出 args1.get(1)
是获取 List 成员的方法。 - WVrock在Java中,只允许有一个varargs
参数,并且它必须是签名的最后一个参数。
但它只是将其转换为数组,所以你应该只将你的两个参数明确声明为数组:
public void doSomething(String[] s, int[] i){
A possible API design in which the calling code looks like
doSomething("a", "b").with(1,2);
通过“流畅”的API
public Intermediary doSomething(String... strings)
{
return new Intermediary(strings);
}
class Intermediary
{
...
public void with(int... ints)
{
reallyDoSomething(strings, ints);
}
}
void reallyDoSomething(String[] strings, int[] ints)
{
...
}
危险在于程序员忘记调用 with(...)
doSomething("a", "b"); // nothing is done
也许这样会更好一些
with("a", "b").and(1, 2).doSomething();
只允许使用一个 vararg
参数。这是因为多个相同类型的 vararg
参数会产生歧义。例如,如果传入两个相同类别的 varargs,将会产生不确定性。
public void doSomething(String...args1, String...args2);
class SuperClass{}
class ChildClass extends SuperClass{}
public void doSomething(SuperClass...args1, ChildClass...args2);
ChildClass继承自SuperClass,因此它可以合法地存在于args1或args2中。这种混淆是为什么只允许一个 varargs
的原因。
varargs
还必须出现在方法声明的末尾。
只需声明特定类型而不是2个数组即可。
public void doSomething(Object... stringOrIntValues) {
...
...
}
然后像这样使用这种方法:
doSomething(stringValue1, stringValue2, intValue1, intValue2,
intValue3);
这是一个旧的帖子,但我认为这仍然会有所帮助。
我找到的解决方案不是很优雅,但它可以工作。我创建了一个独立的类来处理繁重的工作。它只有我需要的两个变量及其getter方法。构造函数自行处理设置方法。
我需要传递方向对象和相应的数据对象。这也解决了可能出现的不对称数据对问题,但这可能只适用于我的使用需求。
public class DataDirectionPair{
Data dat;
Directions dir;
public DataDirectionPair(Data dat, Directions dir) {
super();
this.dat = dat;
this.dir = dir;
}
/**
* @return the node
*/
public Node getNode() {
return node;
}
/**
* @return the direction
*/
public Directions getDir() {
return dir;
}
}
public void method(DataDirectionPair... ndPair){
for(DataDirectionPair temp : ndPair){
this.node = temp.getNode();
this.direction = temp.getDir();
//or use it however you want
}
}
关于为什么只有最后一个参数可以使用可变参数,这只是猜测,但可能是因为允许这样做可能会导致不可决或模棱两可的问题(例如考虑方法或构造函数的最后一个形式参数是特殊的:它可以是可变元素参数,由类型后面的省略号表示。
请注意,省略号(...)是一个独立的标记(§3.11)。虽然可以在它和类型之间放置空格,但这种做法不被推荐。
如果最后一个形式参数是可变元素参数,则该方法是可变元素方法。否则,它是固定元素方法。
method(String... strings, Object... objects)
会发生什么),而只允许非交叉类型会导致复杂性(例如考虑重构,以前非交叉类型突然变成交叉类型),不清楚何时适用或不适用,编译器决定时的复杂性。如果大多数情况下您不会传递大量字符串作为第一个参数,那么您可以提供一堆重载方法,这些方法接受不同数量的字符串并将它们包装在数组中,然后调用以该数组作为第一个参数的方法。
public void doSomething(int... i){
doSomething(new String[0], i);
}
public void doSomething(String s, int... i){
doSomething(new String[]{ s }, i);
}
public void doSomething(String s1, String s2, int... i){
doSomething(new String[]{ s1, s2 }, i);
}
public void doSomething(String s1, String s2, String s3, int... i){
doSomething(new String[]{ s1, s2, s3 }, i);
}
public void doSomething(String[] s, int... i) {
// ...
// ...
}
你可以将你的可变参数转换为数组
public void doSomething(String[] s, int[] i) {
...
}
然后使用一些帮助方法将您的可变参数转换为数组,如下所示:
public static int[] intsAsArray(int... ints) {
return ints;
}
public static <T> T[] asArray(T... ts) {
return ts;
}
然后,您可以使用这些辅助方法来转换您的可变参数。
doSomething(asArray("a", "b", "c", "d"), intsAsArray(1, 2, 3));
String
类型,而另一组参数是int
类型;编译器可以推断出第一个参数何时结束以及第二个参数何时开始,对吗? - arshajiipublic void doSomething(A… as, B… bs)
,而B
是A
的子类型呢?另一方面,Scala 通过允许在一个方法上使用多个参数列表来支持此功能:def doSomething(as: A*)(bs: B*)
。 - DaoWen