Java 单个泛型参数同时接受两种不同的类型

Java 单个泛型参数同时接受两种不同的类型,java,generics,parameters,Java,Generics,Parameters,在下面的场景中,我有一个方法可以接受2个类型为E的数组。据我所知,这个E参数意味着这两个数组可以是任何类型,但它们必须是相同的(正如我从问题中得到的)。 我已经用两个数组(一个整数和一个双精度数组)对此进行了测试,但没有收到任何错误。我收到的输出是'14',这是两个数组的组合大小,没有引发任何错误 有人能解释一下为什么会这样吗 public static <E> void showCombinedLength(E[] array1, E[] array2){ System.o

在下面的场景中,我有一个方法可以接受2个类型为E的数组。据我所知,这个E参数意味着这两个数组可以是任何类型,但它们必须是相同的(正如我从问题中得到的)。 我已经用两个数组(一个整数和一个双精度数组)对此进行了测试,但没有收到任何错误。我收到的输出是'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);
}
public static void showCombinedLength(E[]array1,E[]array2){
系统输出打印项次(array1.length+array2.length);
}
公共静态void main(字符串[]args){
整数[]整数数组={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(整数数组、双数组);
}
输出:

十四,


您的阵列都是对象的阵列。称之为

PrintArray.<Integer>showCombinedLength(integerArray, doubleArray);
PrintArray.showCombinedLength(整数数组、双数组);

编译器将拒绝编译。

您的数组都是对象数组。称之为

PrintArray.<Integer>showCombinedLength(integerArray, doubleArray);
PrintArray.showCombinedLength(整数数组、双数组);

编译器将拒绝编译。

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

publicstaticvoid显示组合长度(Object[]array1,Object[]array2)


所有泛型类型实际上都更改为
对象
。所以
Integer[]
Double[]
实际上都是具有
length
方法的对象数组。这就是代码工作的原因。

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

publicstaticvoid显示组合长度(Object[]array1,Object[]array2)


所有泛型类型实际上都更改为
对象
。所以
Integer[]
Double[]
实际上都是具有
length
方法的对象数组。这就是此代码工作的原因。

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


然而,在java中,数组类型是协变的,因此Integer[]和Double[]都是Object[]的子类(它们也是Number[]的子类)。因此,您的代码将始终编译,无需指定多个类型参数。

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


然而,在java中,数组类型是协变的,因此Integer[]和Double[]都是Object[]的子类(它们也是Number[]的子类)。因此,您的代码将始终编译,不需要指定多个类型参数。

您介意告诉我符号的名称吗?从显示的错误中可以看出,这意味着下面的方法只能接受整数参数。我想详细阅读一下这个符号。使用显式参数类型调用泛型方法。如果不添加
,编译器可以从方法的参数类型推断要使用的泛型参数类型。因此编译器在这里推断数字[]或对象[]。当您不希望这样做,并且明确地想要一个特定的参数类型时,您需要像我一样指定它。例如,当您希望传递一个空的Foo列表,而编译器却推断出一个列表时,这非常有用:尝试执行
String s=Foo(Collections.emptyList())
其中方法定义为
公共静态T foo(列表)
。它不能编译。传递
Collections.emptyList()
。请告诉我符号的名称好吗?从显示的错误中可以看出,这意味着下面的方法只能接受整数参数。我想详细阅读一下这个符号。使用显式参数类型调用泛型方法。如果不添加
,编译器可以从方法的参数类型推断要使用的泛型参数类型。因此编译器在这里推断数字[]或对象[]。当您不希望这样做,并且明确地想要一个特定的参数类型时,您需要像我一样指定它。例如,当您希望传递一个空的Foo列表,而编译器却推断出一个列表时,这非常有用:尝试执行
String s=Foo(Collections.emptyList())
其中方法定义为
公共静态T foo(列表)
。它不能编译。传递
Collections.emptyList()
。实际上,根本不需要指定任何类型参数。它的工作原理与他将其声明为publicstaticvoidshowcombinedlength(Object[]array1,Object[]array2)一样。事实上,根本不需要指定任何类型参数。它的工作原理与他将其声明为publicstaticvoidshowcombinedlength(Object[]array1,Object[]array2)时的工作原理相同。