方法重载尝试给出名称冲突错误。不使用泛型

时间:2016-08-24 04:51:55

标签: java generics arraylist overloading

我有以下代码。

myMethod

我期待name clash的重载,但编译器抱怨{{1}}错误。在搜索SO时,我发现了一个相关的(可能是不确定的)答案here,但我没有使用泛型。所以我的方法不会通过type-Erasure。有人可以解释我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

当您执行此操作ArrayList<ArrayList<Integer>> src 时,您肯定会使用泛型。由于type erasure

  • Integer信息将丢失,即所有通用信息将丢失
  • ArrayList<ArrayList<Integer>> srcArrayList<ArrayList<Double>> src将是相同的。
  • 因此,方法签名对于您定义的两个不符合重载条件的方法都是相同的。

要解决此问题,您可以按照以下方式声明方法并阅读generics wildcard operator

ArrayList<ArrayList< ? extends Number>> src

此处,NumberIntegerDouble的超类。所以你的课程将如下所示

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>>传递给它。

答案 1 :(得分:2)

你在这里遗漏了一个重点。 您仍在代码中使用Generics。

考虑这两个LOC

  1. ArrayList<ArrayList<Integer>> src
  2. ArrayList<ArrayList<Double>> src
  3. 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);
        }
        ...
        ...
    

    正如您所看到的,内部结构正如您所期望的那样使用泛型。

答案 2 :(得分:0)

您肯定使用泛型,并且正在进行类型擦除。你冷了以下

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
    }
}