vararg内部类型声明的java规范
为了只利用java.util.function
中预定义的函数接口,我开始想知道为什么不能在类型声明中指定varargs。例如,我想提供可以像这样使用的API
object.method((x, y, z) -> x + y - z)
其中method
取n个参数的数学函数。下面是我想要的object
接口的样子
interface I {
I method(ToDoubleFunction<double...> f);
}
我确实意识到我可以定义自己的函数接口,或者在尖括号内稍微指定double[]
来更改API。我只是好奇为什么上面提到的方法不可行
编辑:
在注释中,有一个解释说明了为什么上面的示例不能正确使用varargs。Radiodef将我的任务分为两个独立的任务
- why vararg is not allowed as a generic argument and
- why you cannot declare and access vararg by name in Java.
由于问题的标题,我不得不坚持第一个问题。以下是预期的行为:
ToDoubleFunction<double...> lambda = (double... d) -> d[0] + d[1] - d[2];
lambda.applyAsDouble(1, 2, 3);
# 1 楼答案
将方法参数声明为varargs意味着调用方可能会提供任意数量的参数,接收方将像处理数组一样处理这些参数
因此,无论您是否编写:
或
因此,对于编写一个lambda表达式(它实现了一个函数),参数是否被指定为varargs是无关紧要的,特别是当您可以省略参数类型时,这样就没有人会看到
[]
或...
是隐含的因此,当您拒绝使用自己的界面时,您将不得不写下
当然,请记住,您的代码假定有一定的数组长度
有了助手界面,事情可能会变得更简单:
然后你可以写:
类似的事情也适用于等价的
F4
接口等,您可以将它们全部作为ToDoubleFunction<double[]>
处理,但是当您混合使用关于数组长度的不同假设的代码时,编译器不会警告您(当您假设不太可变的arity时,与varargs的问题相同)调用未将参数声明为vararg的数组预期方法时,始终可以使用辅助方法进行包装,该辅助方法不预期varargs:
使用这种方法,您可以像
apply(f, 1, 2, 3)
一样简单地计算函数我有没有提到编译器不会在参数数量不匹配时警告您