方法超载尝试给出名称冲突错误。不使用泛型
我有以下代码。方法超载尝试给出名称冲突错误。不使用泛型
public class myClass {
public static void myMethod(
ArrayList<ArrayList<Integer>> src,
ArrayList<ArrayList<Integer>> dest,
Integer[] selectedIndices) {
}
public static void myMethod(
ArrayList<ArrayList<Double>> src,
ArrayList<ArrayList<Double>> dest,
Integer[] selectedIndices) {
}
}
我期待的myMethod
过载,但name clash
错误的编译器抱怨。在搜索后,我发现了一个相关(可能不确定)的答案here,但我没有使用泛型。所以我的方法不通过type-Erasure。有人能解释我错过了什么吗?
您在这里错过了一个重要的观点。 您仍然在代码中使用泛型。
考虑以下2 LOC
ArrayList<ArrayList<Integer>> src
ArrayList<ArrayList<Double>> src
Java的内部,在这些集合类的实现是使用泛型仅处理这两种情况,因此你的脸Type Erasure问题。
编辑
只要看看这个ArrayList
类
(通常是C:\ Program Files文件\的Java \ jdk1.7.0_45 \ src.zip \ java的\ UTIL \的ArrayList的.java)
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
...
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
...
...
正如你可以看到你所期望的内部结构使用泛型。
java如何决定什么是通用的,哪些不是通用的?通过查看?那么在这里,Java编译器将
@Abhinav在我编辑的答案中查看'ArrayList'的实际结构。你会明白自己在幕后发生了什么 –
当你这样做ArrayList<ArrayList<Integer>> src
你绝对使用泛型。并且由于type erasure,
-
Integer
信息将会丢失,即所有通用的信息将会丢失 -
ArrayList<ArrayList<Integer>> src
和ArrayList<ArrayList<Double>> src
将是相同的。 - 因此,方法签名对于您定义的两种方法都是相同的,这些方法将不符合超载的条件。
为了解决这个问题,你可以如下声明你的方法,并了解generics wildcard operator
ArrayList<ArrayList< ? extends Number>> src
这里,Number
是两个Integer
和Double
一个超类。所以,你的类将是如下
public class MyClass {
public static void myMethod(
ArrayList<ArrayList<? extends Number>> src,
ArrayList<ArrayList<? extends Number>> dest,
Integer[] selectedIndices) {
}
}
你可以传递一个ArrayList<ArrayList<Integer>>
或ArrayList<ArrayList<Double>>
它。
您肯定正在使用泛型,并且类型擦除正在发生。你冷做以下
import java.util.ArrayList;
public class Test {
public static <T> void myMethod(
ArrayList<ArrayList<T>> src,
ArrayList<ArrayList<T>> dest,
Integer[] selectedIndices) {
}
}
EDIT1: 要回答在评论你的问题。它从传入的参数中派生出这个类型。下面是一个关于如何使用它的例子。我还添加了一行会导致编译器失败的行,因为它们的参数类型不匹配。
import java.math.BigDecimal;
import java.util.ArrayList;
public class Test {
public static <T> void myMethod(
ArrayList<ArrayList<T>> src,
ArrayList<ArrayList<T>> dest,
Integer[] selectedIndices) {}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> srcInteger = null;
ArrayList<ArrayList<BigDecimal>> srcBigDecimal = null;
Integer[] indexes = null;
myMethod(srcInteger, srcInteger, indexes);
myMethod(srcBigDecimal, srcBigDecimal, indexes);
myMethod(srcInteger, srcBigDecimal, indexes); // <- this will not compile
}
}
java如何决定什么是通用的,哪些不是通用的?通过查看?那么在这里,Java编译器将
你是什么意思“我不使用泛型”? –
@PeterRader我的意思是,我的方法签名里面没有任何东西像。 –
Abhinav