为什么 Java 可变参数不支持集合?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6898653/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:49:57  来源:igfitidea点击:

Why doesn't Java varargs support collections?

javacollectionslanguage-featuresvariadic-functions

提问by tb189

In my Java code I often use the very handy method(Class... args)varargs. As far as I know, they allow you to pass any amount of Classobjects or an array of Class[]. Since I also often use the Java collection classes, I am frustrated by the lack of compatibility between both. As a result, I end up doing collection.toArray(), but that has some type safety issues.

在我的 Java 代码中,我经常使用非常方便的method(Class... args)可变参数。据我所知,它们允许您传递任意数量的Class对象或Class[]. 由于我也经常使用 Java 集合类,我对两者之间缺乏兼容性感到沮丧。结果,我最终做了collection.toArray(),但这有一些类型安全问题。

So now for the question: why doesn't Java allow instances of Iterable<T>as vararg arguments, as long as the generic type fits the T...type of the vararg? Doesn't everyone use lists, sets, etc. all the time? Is there an easy, type-safe way to provide the conversion from collection to vararg?

那么现在问题来了:Iterable<T>只要泛型类型适合T...vararg的类型,为什么 Java 不允许as vararg 参数的实例?不是每个人都一直使用列表、集合等吗?有没有一种简单的、类型安全的方法来提供从集合到可变参数的转换?

回答by Joachim Sauer

The reason is simple: a variable arity parameter is simply an old-school array paramater with some additional metadata that tells the compiler to provide some syntactic sugar (namely, it allows implicit array creation).

原因很简单:变量 arity 参数只是一个带有一些额外元数据的老式数组参数,它告诉编译器提供一些语法糖(即,它允许隐式数组创建)。

So from the perspective of the JVM Object...is pretty much the same as Object[]. Allowing collections as well would require a more invasive change to the JVM (which has no explicit support for collections to date).

所以从 JVM 的角度来看,Object...Object[]. 允许集合也需要对 JVM(迄今为止没有明确支持集合)进行更具侵入性的更改。

Note that if you want to support both ways, then making the collection-based method is probably the better approach:

请注意,如果您想同时支持两种方式,那么使用基于集合的方法可能是更好的方法:

public void frobnicate(Object... args) {
  frobnicate(Arrays.asList(args));
}

public void frobnicate(Iterable<Object> args) {
  // do stuff
}

The reason for this is that using Arrays.asList()is usuallya cheaper operation than Collection.toArray()(because it creates a simple wrapper).

这样做的原因是,使用Arrays.asList()通常比一个更便宜的操作Collection.toArray()(因为它创建一个简单的包装)。