我正在使用varargs并且知道: -
public void myMethod(String... args, int val){}
myMethod方法的变量参数类型String必须是 最后一个参数。
如果两者都像String
那样,错误的给定是相当的,但在这种情况下,我将int
设置为第二个参数,因此在运行时JVM
可以检查类型论证和可以区分如下: -
myMethod("HI", "HELLO", 9)
这不可行。我遗漏的任何其他方面都会产生错误?
答案 0 :(得分:5)
语言设计师选择不允许这样做有很多原因:
您的示例在理论上可以解决,但限制会非常苛刻:例如,编译器很难看到第一个varargs参数在这种情况下结束的位置
void foo(Object... objs, String... s)
foo("a", "b", "c")
另一个例子是:
void bar(int... ints, long... longs)
foo(1, 2, 3, 4)
您可能认为int
和long
是不同的数据类型,但不幸的是,由于扩大转化次数,可能会使用预期long
的整数。另一个例子涉及拳击:
void baz(Object... objs, int... ints)
baz(1, 2, 3, 4)
int
和Object
没有直接关系,但int
可以转换为Integer
,这是Object
的子类。
您拥有的重载方法和变量参数越多越复杂。
varargs
不是参数属性,而是方法修饰符标志(ACC_VARARGS
)。这意味着方法是可变参数(最后一个参数是varargs)或者它不是。 String...
与String[]
相同,只是您不需要在使用地点创建数组。您可以声明方法
void foo(String[] strings, int i)
并将其命名为
void foo({ "a", "b" }, 2)
只有2次击键,没有varargs参数引入的所有挣扎。
我已经在JVM-language编译器上工作了一年多,我也考虑过添加这个功能。但是,方法解析系统已经极其复杂(我决定包含自定义infix
和prefix
运算符/方法以及命名和默认参数无法实现任何更简单的方法,多个varargs参数都不会让它变得更容易。
答案 1 :(得分:0)
错误消息是正确的。如果你使用varargs,它必须是最后一个参数。你可以说它可以解决它,但事实并非如此。只需交换参数的顺序。
答案 2 :(得分:0)
当你在随机位置使用varargs重载方法时,消歧将成为一场噩梦...(不是说多个varargs)。
答案 3 :(得分:0)
这是在JLS section 8.4.1中指定的。语言规范要求将其作为形式参数列表的一部分:
FormalParameterList: ReceiverParameter FormalParameters , LastFormalParameter LastFormalParameter
LastFormalParameter
令牌是定义和允许varargs的地方。
LastFormalParameter: {VariableModifier} UnannType {Annotation} ... VariableDeclaratorId FormalParameter
注意...
。这是正式参数语法中唯一允许这样做的地方。 FormalParameters
没有这个限额。
FormalParameters: FormalParameter {, FormalParameter} ReceiverParameter {, FormalParameter}