方法重载尝试给出名称冲突错误。不使用泛型
Method overload attempt gives name clash error. Not using Generics
我有以下代码。
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
错误。在搜索 SO 时,我找到了一个相关的(可能不确定)答案 , but I am not using Generics. So my methods don't go through the type-Erasure。有人可以解释我错过了什么吗?
当你这样做时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
的超级 class。所以你的 class 将如下所示
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>>
传递给它。
您在这里遗漏了一个重点。 您仍在代码中使用泛型。
考虑这 2 个 LOC
ArrayList<ArrayList<Integer>> src
ArrayList<ArrayList<Double>> src
Java 在内部,在这些集合的实现中 classes 仅使用泛型来处理这两种情况,因此您面临 Type Erasure 问题。
编辑
看看这个ArrayList
class
(一般在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);
}
...
...
如您所见,内部结构如您所料使用了泛型。
您肯定在使用泛型,并且正在进行类型擦除。你冷做以下
import java.util.ArrayList;
public class Test {
public static <T> void myMethod(
ArrayList<ArrayList<T>> src,
ArrayList<ArrayList<T>> dest,
Integer[] selectedIndices) {
}
}
编辑 1:
在评论中回答你的问题。它从传入的参数派生类型。下面是一个关于如何使用它的示例。我还添加了一行,这将导致编译器失败,因为它们的参数类型不匹配。
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
}
}
我有以下代码。
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
错误。在搜索 SO 时,我找到了一个相关的(可能不确定)答案
当你这样做时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
的超级 class。所以你的 class 将如下所示
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>>
传递给它。
您在这里遗漏了一个重点。 您仍在代码中使用泛型。
考虑这 2 个 LOC
ArrayList<ArrayList<Integer>> src
ArrayList<ArrayList<Double>> src
Java 在内部,在这些集合的实现中 classes 仅使用泛型来处理这两种情况,因此您面临 Type Erasure 问题。
编辑
看看这个ArrayList
class
(一般在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);
}
...
...
如您所见,内部结构如您所料使用了泛型。
您肯定在使用泛型,并且正在进行类型擦除。你冷做以下
import java.util.ArrayList;
public class Test {
public static <T> void myMethod(
ArrayList<ArrayList<T>> src,
ArrayList<ArrayList<T>> dest,
Integer[] selectedIndices) {
}
}
编辑 1: 在评论中回答你的问题。它从传入的参数派生类型。下面是一个关于如何使用它的示例。我还添加了一行,这将导致编译器失败,因为它们的参数类型不匹配。
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
}
}