2012-04-13 24 views
5

私は引数としてList<?>をとるメソッドを持っています。 methodJavaジェネリック型引数

public static String method(List<?> arg){ 
    // Do something based on type of the list 
} 

//I call the method as below 
List<ClassA> listA = new ArrayList<ClassA>(); 
List<ClassB> listB = new ArrayList<ClassB>(); 
method(listA); 
method(listB); 

argClassAまたはClassBListListであれば、どのように私は知っていますか?

+2

パラメータタイプを「」と宣言することは、実際のタイプに興味がないことを意味します。 – biziclop

+0

これと重複しています。http://stackoverflow.com/questions/1942644/get-generic-type-of-java-util-list – evanwong

+0

@evanwong - 私がその欺瞞に同意するかどうかはわかりません。 – djangofan

答えて

3

は「Romainと呼ばれる?>、あなたはどこにでもパラメータ化タイプを使用するつもりはありません。どちらかは、特定のタイプに行く(お使いの場合には、それはリスト<文字列を思わ>意味)、または非常に一般的なリスト<オブジェクト>「

はまた、私はあなたが質問を使用する場合は、実行時(具体化されるまで、コンパイラ文句を言わないキャッチ型の不一​​致をマークすることを信じていると、消去をバイパスして、効果的なジャワのP.119)、かつ効果的にジェネリック型を使用することで得られる利益をなくす

リスト<オブジェクト>を使用して、それをAまたはBにキャストしようとすると、instanceOfを使用している可能性があります。私はそれよりもそれを行うより良い方法があると確信しています。

+1

OPのための+1は、効果的にジェネリックタイプを使用することで得られる利益を取り除きます。 – jahroy

+1

は、 "ジェネリックスを使用していませんが、コンパイラの警告を取り除きたい"という意味です。 – user949300

+3

-1この回答は悪いコーディングの習慣を奨励するためです。ジェネリック型の引数を取るメソッドを定義するのが適切な方法です。これは型の安全性を提供し、乱雑なキャストを必要としません。 jahroyの回答を参照してください。 –

1

あなたの例では、Listのジェネリック型引数はどのようなものか分かりません。それらはインスタンスレベルで消去されます。あなたが<を使用する場合は、ユーザがその答えから

14

技術的には、オブジェクトが特定の型であるかどうかを確認するために、あなたCAN使用instanceofを話します。

ただし、... 良い考えです。

あなたのメソッドを宣言した方法、それは、任意のタイプのリストを受け入れることができ、必ずしもAまたはB

であることを行っていないので、それはあなたが何をしようとして伝えるのは難しいですおそらく、あなたのメソッドを一般的にするべきです。

あなたはこのようにそれを行うことができます:あなたは、リストの最初の要素を返すジェネリックメソッドを作成したい場合は、

public static <T> String method(List<T> arg) { 
    // We now know that the type of the list is T, which is 
    // determined based on the type of list passed to this 
    // method. This would demonstrate the point better if 
    // the return type was T, but I'm leaving the return type 
    // as String, because that's what your code returns. 
} 

をここでより良い例うこれは次のようになります:

public static <T> T firstElement(List<T> theList) { 
    if (theList == null) { 
     return null; 
    } 
    T objectOfTypeT = theList.get(0); 
    return objectOfTypeT; 
} 

タイプは現在Tです。

このメソッドを汎用化したので、Listで使用されているのと同じ型を返すことができます。

あなたは通常、theList.get(0)を返しますが、ジェネリックの目的をより明確にするために行を追加しました。構文の

説明:

  • <T>は、この方法はT.

    という名前の型パラメータ
  • を取り、すぐに次のTは、戻り値の型(ちょうどあなたが通常と同様であることを示しています文字列、整数などを返します)。

  • ListパラメータのTは、コンパイラがTの内容をコンパイラに知らせる方法です。

これは、コンパイラが言うことができます:誰かがTよりも、このメソッドに文字列のリストを渡した場合、リストはタイプTのもある... "このメソッドは、型Tの何かがああ見て期待してい文字列でなければなりません。誰かがこのメソッドに整数のリストを渡した場合、Tは整数でなければなりません。

対照的に、あなたの方法はだけ文字列を返すことができ、それはで使用されているどのようなタイプは考えていませんリスト。 AとBの両方がTheParentClassという名前の同じクラスを拡張した場合も


...

、あなたはこのようなあなたのメソッドを宣言することができます:

public static String method(List<? extends TheParentClass> arg) 

そのように、あなたが知っているだろうコンパイル時の型チェックの恩恵を受けることができます。

+0

"?extends TheParentClass"の最後の例は、おそらくどのようにですか?使用されることを意味していました。 ?の使用を許可する? David Masonの示唆しているように、悪い習慣ではあるが、合法である。私は彼がそれを釘付けにしたので、ジャフロイは私よりもむしろこの質問に対する答えを与えられるべきだと私は思う。 – djangofan

関連する問題