2016-08-24 21 views
1

我有以下代码。方法超载尝试给出名称冲突错误。不使用泛型

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

你是什么意思“我不使用泛型”? –

+0

@PeterRader我的意思是,我的方法签名里面没有任何东西像。 – Abhinav

+1

的占位符。您正在使用泛型。 –

回答

2

您在这里错过了一个重要的观点。 您仍然在代码中使用泛型。

考虑以下2 LOC

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

正如你可以看到你所期望的内部结构使用泛型。

+0

java如何决定什么是通用的,哪些不是通用的?通过查看<>?那么在这里,Java编译器将看作一些? – Abhinav

+0

@Abhinav在我编辑的答案中查看'ArrayList'的实际结构。你会明白自己在幕后发生了什么 –

3

当你这样做ArrayList<ArrayList<Integer>> src你绝对使用泛型。并且由于type erasure

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

为了解决这个问题,你可以如下声明你的方法,并了解generics wildcard operator

ArrayList<ArrayList< ? extends Number>> src 

这里,Number是两个IntegerDouble一个超类。所以,你的类将是如下

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>>它。

+0

谢谢。可能是我对泛型的基础薄弱。但是,我没有具体说明该功能可以预期的功能。例如。 ArrayList和Integer。这些可以被认为是泛型? – Abhinav

+0

java如何决定什么是通用的,哪些不是通用的?通过查看<>?那么在这里,Java编译器将看作一些? – Abhinav

+0

如果您使用< >(尖括号),表示您直接或间接使用泛型。在这种情况下,您正在使用预定义的通用列表,即ArrayList,它支持使用泛型的每个数据类型(通用数据类型)。 –

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

java如何决定什么是通用的,哪些不是通用的?通过查看<>?那么在这里,Java编译器将看作一些? – Abhinav