java - 如何解释这种看似不一致的 Java 可变参数行为?

标签 java arrays generics variadic-functions

如果我写Java方法

public static void f(int... x) {
    for (int a: x) {
        System.out.println(a);
    }
}

然后我可以通过

调用这个方法
f(1, 2, 3);

还有

f(new int[]{1, 2, 3});

并且两个调用的处理方式完全相同。然而,这两个电话

Arrays.asList(1, 2, 3)              // (a) produces a three-element Integer list

Arrays.asList(new int[]{1, 2, 3})   // (b) produces a one-element list of Integer arrays

不一样对待。 The section on evaluating arguments在 JLS 中声明“m 的最终形式参数对于某些 T 必须具有类型 T[]”那么为什么“final”不是上面的情况 (b) 中的形式参数”不是 一个整数数组,它会创建一个三元素列表,如情况 (a)?

我唯一能想到的是 Arrays.asList 是通用的,一些关于类型兼容性(在 JLS 第 15.12.4.2 节中提到)在这里发挥作用,但我不能完全确定 JLS 中使这两种情况不同的实际句子。

JLS 中的评论谈到需要仔细设计这些语义,以处理“在具有已删除泛型的 Java 虚拟机中出现的参数化类型和数组类型”之间的相互作用,但我们最终得到的是我的函数 fArrays.asList 似乎表现不一致。在前一种情况下,我可以“解压”或“打包”我的参数,一切都是一样的;在后一种情况下,这两种情况是不同的。

这在语言律师术语中是如何解释的?

最佳答案

Arrays.asList被定义为具有参数 T... , 正文会将其视为 T[] 类型的一个参数.然而,T 必须是引用类型(与任何类型参数一样),并且 int不是引用类型。因此,无法制作 new int[]{...}出于 varargs 目的与数组兼容。 (结果将是 List<int>,这是不允许的。)唯一的选择是将其视为单个对象,因此是 T。这里将是int[] ,这是一个引用类型,函数将返回一个 List<int[]> .

我想这就是原因,尽管我仍然需要查找确切的语言。可能涉及类型推断规则,我还没有掌握。

但是,我确实尝试过这个:

List x = Arrays.asList(new int[]{1, 2, 3});
List y = Arrays.asList(new Integer[]{1, 2, 3});
System.out.println(x.size());   
System.out.println(y.size());   

(请注意,我故意使用了 List 原始类型,我不会在实际代码中这样做)。输出:

1
3

关于java - 如何解释这种看似不一致的 Java 可变参数行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27142662/

相关文章:

java - 使用 Stream.of 检查 List<String> 是否以另一个字符串开头

java - 从 java 属性文件中读取 int[]

c++ - 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针?

python - MATLAB 相当于 Python 的负索引

c# - 使用 List<T> 创建允许 T 的子类的接口(interface)

java - 为什么 getAnnotation 不接受 Class<?扩展注解>

java - SQL 查询查找与 Toplink 中的日期相等的行

java - 如何检查 Java 枚举中的值?

java - DBUnit 中的重置序列?

Java反射: getting correct type of parameterized generic superclass method