如何确定varargs数组的组件类型?

Pau*_*ton 15 java generics variadic-functions

使用varargs时,结果数组的组件类型是如何确定的?

例如,该程序是否保证打印true或在技术上未指定其行为?

public static void main(String[] args) {
    foo("", 0);
}

static <T> void foo(T... arr) {
    System.out.println(arr.getClass() == Serializable[].class);
} 
Run Code Online (Sandbox Code Playgroud)

Cap*_*tti 1

好吧,我对此不是 100% 确定,但我认为这与 varargs 无关,而更像是动态绑定、泛型和类型擦除。

“Java 中的数组是协变的,但泛型不是。换句话说,String[] 是 Object[] 的子类型,但 Stack 不是 Stack 的子类型。”

资料来源: http://algs4.cs.princeton.edu/13stacks/

因此,为了回答您的问题,这种行为已被指定记录和预期。

在《Effective Java》一书中,Joshua Bloch 是这样解释的:

数组与泛型类型有两个重要的不同之处。首先,数组是协变的。这个听起来吓人的词的意思很简单,如果 Sub 是 Super 的子类型,那么数组类型 Sub[] 就是 Super[] 的子类型。相比之下,泛型是不变的:对于任何两个不同的类型 Type1 和 Type2,List<Type1> 既不是 List<Type2> 的子类型也不是其超类型 [JLS, 4.10; 萘他林07,2.5]。您可能认为这意味着泛型有缺陷,但可以说是数组有缺陷。

您可能会问我为什么要谈论数组?嗯,因为可变参数最终会变成数组。

“在过去的版本中,采用任意数量值的方法要求您在调用该方法之前创建一个数组并将值放入数组中。”

“确实必须在数组中传递多个参数,但可变参数功能会自动执行并隐藏该过程。”

来源: https ://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html