为什么我不能制作两个重载方法,这些方法的参数都是数组列表,但是数据类型不同?
public class test {
public static void main(String[] args){
ArrayList<Integer> ints = new ArrayList<Integer>();
ints.add(1);
ints.add(2);
ints.add(3);
ints.add(4);
ints.add(5);
showFirst(ints);
ArrayList<Double> dubs = new ArrayList<Double>();
dubs.add(1.1);
dubs.add(2.2);
dubs.add(3.3);
dubs.add(4.4);
dubs.add(5.5);
showFirst(dubs);
}
public static void showFirst(ArrayList<Integer> a)
{
System.out.println(a.remove(0));
}
public static void showFirst(ArrayList<Double> a)
{
System.out.println(a.remove(0));
}
}
我在eclipse中,它强调导致代码为红色的问题,并提供此消息:Method showFirst(ArrayList<Integer>) has the same erasure showFirst(ArrayList<E>) as another method in type test
我能让它发挥作用的唯一方法是我添加其他参数,例如, int b
之后的showFirst(ArrayList<Integer> a
和, int b
之后的showFirst(ArrayList<Double> a
。
有没有办法让这段代码按照我的意图运作?如果没有,我想知道为什么会这样。
运行程序会生成以下错误消息:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method showFirst(ArrayList<Integer>) in the type test is not applicable for the arguments (ArrayList<Double>)
at test.test.main(test.java:25)
编辑:
使用或者,如果我想做我需要数据类型的事情,例如:
public static int[] reverseInArray(ArrayList<Integer> a)
{
int n = a.size();
int[] b = new int[n];
while(n > 0)
{
b[n] = a.remove(0);
n--;
}
return b;
}
public static double[] reverseInArray(ArrayList<Double> a)
{
double n = a.size();
double[] b = new int[n];
while(I > 0)
{
b[n] = a.remove(0);
n--;
}
return b;
}
答案 0 :(得分:12)
在运行时,由于type erasure,每个ArrayList<Whatever>
都会转换为ArrayList
(原始)。所以,只需要一个接收List<? extends Number>
的方法。
//renamed to show what the method really does
public static void removeFirst(List<? extends Number> a) {
System.out.println(a.remove(0));
}
请注意,上述方法仅适用于List
s(ArrayList
,LinkedList
以及List
的其他实现),这些实现声明持有从{延伸的{ {1}}。如果您希望/需要一种方法来删除包含任何类型的Number
中的第一个元素,请改为使用List
:
List<?>
请记住始终program to interfaces instead of specific class implementation。
答案 1 :(得分:3)
泛型仅在编译时强制执行。在运行时,ArrayList
是ArrayList
。
您可以在这种特殊情况下结合使用这两种方法:
public static void showFirst(ArrayList<? extends Number> a)
{
System.out.println(a.remove(0));
}
答案 2 :(得分:3)
因为泛型在运行时被擦除。换句话说,您的代码不知道这两种方法是不同的。实际上,您还有另一个编译器错误,您没有告诉我们:
Method showFirst(ArrayList<Integer>) has the same erasure showFirst(ArrayList<E>) as another method in type Main
答案 3 :(得分:3)
...因为type erasure,你的通用参数在运行时是未知的,因此被覆盖的方法会共享一个模糊的签名。
答案 4 :(得分:2)
仅使用此方法,因为泛型仅在编译时可用,因此,两种方法都编译为相同的签名。因此,调用哪种方法
是不明确的public static void showFirst(ArrayList<? extends Number> a)
{
System.out.println(a.remove(0));
}