【问题标题】:Single generic parameter accepts two different types at the same time单个泛型参数同时接受两种不同的类型
【发布时间】:2013-01-06 14:42:48
【问题描述】:

在以下场景中,我有一个接受 2 个 E 型数组的方法。据我了解,此 E 参数意味着两个数组都可以是任何类型,但它们必须相同(因为我从 @987654321 派生@ 题)。 我已经用两个数组进行了测试,一个整数和一个双精度,但我没有收到任何错误。我收到的输出是“14”,这是两个数组的组合大小,没有抛出任何错误。

有人能解释一下为什么会这样吗?

public static <E> void showCombinedLength(E[] array1, E[] array2){
    System.out.println(array1.length + array2.length);
}

public static void main(String[] args) {
    Integer[] integerArray = {1, 2, 3, 4, 5, 6, 7};
    Double[] doubleArray = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
    PrintArray.showCombinedLength(integerArray, doubleArray);
}

输出:

14

【问题讨论】:

    标签: java generics parameters


    【解决方案1】:

    当您在方法定义中定义一个泛型类型时,您只能将该方法与两个相同类型的数组一起使用。

    但是,在 java 中,数组类型是协变的,因此 Integer[] 和 Double[] 都是 Object[] 的子类(它们也是 Number[] 的子类)。所以你的代码会一直编译,不需要指定多个类型参数。

    【讨论】:

    • 其实根本不需要指定任何类型参数。就像他声明 public static void showCombinedLength(Object[] array1, Object[] array2) 一样
    【解决方案2】:

    您的数组都是对象数组。调用它

    PrintArray.<Integer>showCombinedLength(integerArray, doubleArray);
    

    编译器会拒绝编译。

    【讨论】:

    • 您介意告诉我 符号的名称是什么吗?据我从显示错误中可以看出,这意味着下面的方法只能接受整数参数。我想了解一下这个符号。
    • 使用显式参数类型调用泛型方法。
    • 如果不添加&lt;Integer&gt;,则让编译器根据方法的参数类型推断要使用的泛型参数类型。所以编译器在这里推断 Number[] 或 Object[]。当您不想要那个,并且明确地想要一个特定的参数类型时,您需要像我一样指定它。例如,当您想要传递一个空的 Foo 列表而编译器推断出一个 List 时,这很有用:尝试执行 String s = foo(Collections.emptyList());,其中方法定义为 public static &lt;T&gt; T foo(List&lt;T&gt; list)。它不编译。通过Collections.&lt;String&gt;emptyList().
    【解决方案3】:

    泛型是在 1.5 版中引入 Java 的。由于向后兼容,Java 字节码不知道某些方法是通用的,而另一种则不是。这就是为什么编译后你的方法真的是:

    public static void showCombinedLength(Object[] array1, Object[] array2)

    所有泛型类型都真正更改为Object。所以Integer[]Double[] 都是具有length 方法的对象数组。这就是这段代码有效的原因。

    【讨论】:

      猜你喜欢
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多