我有两种类型的列表:
ArrayList<String> sList;
ArrayList<Resource rList;
我可以在资源对象上调用.getName()
方法。
我希望能够通过调用这样的printList(list)
元词来打印出这些列表中的任何一个:
printList(sList);
printList(rList);
他们的代码看起来像这样:
private static void printList(ArrayList<String> list){
for(String s : list){
System.out.println(s + ", ");
}
}
private static void printList(ArrayList<Resource> list){
for(Resource r : list){
System.out.println(r.getName() + ", ");
}
}
我没有任何特别的理由使用private static
,它恰好就是这样,因为eclipse建议它。
然而,代码不起作用。 Eclipse给出了以下错误:
“方法printList(ArrayList)具有相同的擦除 printList(ArrayList)作为GUI“
类型中的另一种方法
GUI
是我的班级。怎么了?
答案 0 :(得分:6)
由于type erasure两种方法具有相同的签名,即编译器都看到它们
作为
private static void printList(ArrayList list)
使得彼此无法区分并导致编译错误。如果希望编译代码,则需要更改签名,例如
private static void printStringList(ArrayList<String> list)
private static void printResourceList(ArrayList<Resource> list)
或者如果toString
已覆盖所有List
类型,则可以使用泛型格式(例如
private static <T> void printList(List<T> list) {
for (T t: list) {
System.out.println(t);
}
}
答案 1 :(得分:2)
在类型擦除过程中,Java编译器会擦除所有类型参数,如果type参数是有界的,则将每个参数替换为第一个绑定,如果type参数是无界的,则替换为Object。
Erasure of Generic Types JVM将其视为
private static void printList(ArrayList<> list){
for(String s : list){
System.out.println(s + ", ");
}
}
private static void printList(ArrayList<> list){
for(Resource r : list){
System.out.println(r.getName() + ", ");
}
}
答案 2 :(得分:2)
您的两个printList
方法具有相同的方法签名。使用不同的泛型类型不会使参数与重载目的不同。编译器只看到
private static void printList(ArrayList list)
private static void printList(ArrayList list)
所以它无法确定你想要调用哪种方法。
如果您想要两个单独的printList
方法,则需要使用不同的签名。
注意static
只是因为方法不访问任何实例变量。
答案 3 :(得分:1)
泛型资源/字符串仅在编译器时存在。在运行时,无法区分这两种方法