2016-08-24 5 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エラーを訴えます。 SOを検索すると、関連する(おそらく、わからない)回答hereが見つかりましたが、Genericsは使用していません。だから、私の方法はtype-Erasureを通過しません。誰かが何が欠けているのか説明できますか?

+2

「ジェネリックスを使用していません」とはどういう意味ですか? –

+0

@PeterRader私のメソッドシグネチャにはのようなものはありません。 – Abhinav

+1

は、のプレースホルダです。あなたはジェネリックスを使用しています。 –

答えて

2

重要な点が1つあります。 コードでGenericsを使用しています。

は、これらのコレクションクラスの実装でのみこれらの状況の両方を処理するためにジェネリックを使用して、したがって、あなたが直面している、これら2 LOC

  1. ArrayList<ArrayList<Integer>> src
  2. ArrayList<ArrayList<Double>> src

内部のJavaを考えてみましょうType Erasure問題。


EDIT

ちょうどこのArrayListクラスを見て
(これはCで通常:\プログラムファイル\の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あなたは間違いなくジェネリックを使用しています。

  • Integer情報が失われます、type erasureに起因すると、すなわち、すべての一般的な情報が
  • ArrayList<ArrayList<Integer>> src
  • を失われ、 ArrayList<ArrayList<Double>> srcは同じになります。
  • したがって、メソッドシグネチャは、定義した両方のメソッドで同じになりますが、オーバーロードの対象にはなりません。

これを解決するには、以下のようにあなたのメソッドを宣言し、約generics wildcard operator

ArrayList<ArrayList< ? extends Number>> src 

ここで、NumberIntegerDouble両方のスーパークラスです読み取ることができます。だからあなたのクラスは、あなたがそれにArrayList<ArrayList<Integer>>ArrayList<ArrayList<Double>>を渡すことができるよう

public class MyClass { 

    public static void myMethod(
      ArrayList<ArrayList<? extends Number>> src, 
      ArrayList<ArrayList<? extends Number>> dest, 
      Integer[] selectedIndices) { 
    } 
} 

の下になります。

+0

ジェネリックスの私の根本が弱いかもしれない。しかし、私は関数が何を期待できるかを正確に指定していません。例えば。 ArrayListと整数。これらはGenericsと考えることができますか? – Abhinav

+0

Javaはどのようにして一般的なものとそうでないものを決定しますか? <>を見て?そこでここでは、Javaコンパイラはをいくつかはと見なしていますか? – Abhinav

+0

< >(角カッコ)を使用すると、ジェネリックを直接的または間接的に使用していることを意味します。この場合、Generics(Generic Dataタイプ)を使用して、すべてのデータタイプをサポートする事前定義済み汎用リスト、つまり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

関連する問題