2009-05-25 9 views

答えて

10

genericsの目的を無効にするようだが、ここではそれが行く:

Stack<Object>s = new Stack<Object>(); 
s.add("hello"); 
s.add(1);   // int is autoboxed to Integer 

キャッチがStackからObject Sを取得するとき、どのような種類を見つけるためにいくつかの努力が必要になるだろうということになります各要素である - それはinstanceofと型キャストを使用して必要になります。

while (!s.isEmpty()) { 
    Object e = s.pop(); 

    if (e instanceof String) 
    System.out.println("String: " + (String)e); 
    else if (e instanceof Integer) 
    System.out.println("Integer: " + (Integer)e); 
    else 
    System.out.println("Other type: " + e); 
} 

そして今、我々は5日、ジェネリック医薬品の前に前のJavaの脆弱なコードに似た何かを言語に追加されたています。

+1

危険性は、後でアイテムを取得するときに、オブジェクトタイプのチェックを書く必要があります。 – Joset

+0

絶対に - 私はちょうど編集としてその部分を追加し終えました。 – coobird

6

一般的に、継承を使用してこれを解決する必要があります。おそらくマーカーインターフェイスを使用して:あなたは、単一のクラスでのインターフェイスの数に制限を実装することができ、あなたはどこにでもクラスhierchyで余分なインターフェイスを追加することができますので、

interface MyMarker 
{ 
} 

class Foo implements MyMarker 
{ 
} 

class Bar implements MyMarker 
{ 
} 

インタフェースは、このようなケースでは実用的です。あなたはその後、同じスタック内のFooとバーを置くことができ

は:

Stack<MyMarker> s = new Stack<MyMarker>(); 
s.add(new Foo()); 
s.add(new Bar()); 

これは、それがすべてで可能かどう移動するための方法です。それ以外の場合は、coobirdが示唆するようにしなければなりません。

+2

これは間違いなく良い方法です - "instanceof"のif-elseifラダーがある場合、その解決策は通常継承されます。 – coobird

0

スタックの汎用引数は、すべての要素ランタイム型の共通のスーパータイプである必要があります。完全に異種のコレクションの場合、Objectはすべての参照タイプの共通のスーパータイプです。だから、:

Queue<Object> stack = Collections.asLifoQueue(new ArrayDeque<Object>()); 
stack.add("red"); 
stack.add(Color.GREEN); 
stack.add(stack); 

はもちろん、あなたがスタックからそれらの要素をポップに来たとき、あなたは(そしておそらくキャスト)適切なコードにルーティングするチェックinstanceofを行う必要があります。

間接参照のレイヤーを導入する方がよいでしょう。オブジェクトをキューに直接置くのではなく、意味のあるオブジェクトにラップしてください。 instanceofチェックはすべて、必要な操作を実行する(仮想)メソッドへの呼び出しで置き換えることができます。多形性がどのようになっているのか。

関連する問題