2012-02-29 5 views
0

Java Genericsの新機能です。しかし、私は多くのサマリーリンクと例を読んだ。しかし、私は最も簡単な方法を得ることができません。私はsomenoeが助けることを望みます:Javaジェネリックスで安全でないキャストの警告を避けるには

定義されていないオブジェクトを別のオブジェクトにマップするHashMapを作成します。両方のオブジェクトは、StringまたはIntegerのいずれかです。

だから私は、この書いた:これまでのところは良い

private final HashMap<L, R> left2Right = new HashMap<L, R>(); 

Extractor<?> extLeft = Extractor.getInstance(0); 
Extractor<?> extRight = Extractor.getInstance(1); 

L leftVal = extLeft.extract(d, i); 
R rightVal = extRight.extract(d, i); 

this.left2Right.put(leftVal, rightVal); 

を...しかし、私は、抽出-オブジェクトを実装する問題を抱えています。それらは工場のパターンによってインスタンス化される。

abstract class Extractor<E> { 
    abstract E extract(DTable source, int row); 

    static <E> Extractor<E> getInstance(int type) { 
     if(type == 0) 
      return new IntExtractor(); 
     else 
      return new StringExtractor(); 
    } 
} 

class IntExtractor extends Extractor<Integer> { 

    @Override 
    Integer extract(DTable source, int row) { 
     int value = 5; 
     return new Integer(value); 
    } 

} 

class StringExtractor extends Extractor<String> { 

    @Override 
    String extract(DTable source, int row) { 
     String retVal = "hello"; 
     return retVal; 
    } 

} 

それはコンパイルが、私は私が間違っているのは何E.に整数/文字列をキャストにUNSAVEキャストの警告を得る:私はこのようにそれをしなかった(simplyfied)?私は知っている、私は単に警告を抑えることができます。しかし、私はこれがJavaのジェネリックの利点であるべきだと思ったのですか?私はこのタイプのキャストを保存することはできません。私は知らないので、「E」タイプは本当に「...」です。

何か基本的に間違っていますか?

注: 私は最初の回答からいくつかの情報を使用した後、私は「新しい」という質問への私のコードを編集した...

+0

私はこの問題にあるすべてを私たちに言っていないと感じています... – Bombe

答えて

0

PEの両方がなぜこれほど抽出器の入力に使用されていないように見えますあなたはそれらを持っていますか?ちょうどintStringを返してください。

2

エクストラクタは実際には一般的ではありません。

public interface Extractor<P> { 
    P extract(DTable source, int row); 
} 

が、その後非ジェネリック実装を行います:それはあなたのような何かをしたいように聞こえる

IntExtractor<String> extractor = new IntExtractor<String>(); 
String x = extractor.extract(...); 

class IntExtractor implements Extractor<Integer> { 

    Integer extract(DTable source, int row) { 
     int value = 5; 
     return new Integer(value); 
    } 
} 

基本的に、あなたの現在のコードは、その中で、私は書くことができ、壊れています

...明らかに失敗しますが、実行時にのみ発生します。

+0

Ok ...私はすべてを投稿しませんでした。インターフェイスの代わりに私はこのような抽象クラスを使用しています: – Sauer

+0

@Sauer:コメントにコードを入れるのではなく質問を編集する必要がありますが、同じ原則が適用されると思います。具体的なクラスは、ジェネリッククラスをサブクラス化する場合でも、ジェネリックではありません。 –

1

私はあなたが何か基本的に間違っていると言いたいと思います。 IntExtractorとStringExtractorの場合、ジェネリックは必要ありません。ただ、問題は、それ自体はあなたのコードではありません方法

Integer extract(DTable source, int row) 

String extract(DTable source, int row) 
1

を定義します。安全なキャストがなければ、タスクそのものを解決することはできません。もう一度、あなた自身の文章を読む:私は 別のものに1つの未定義オブジェクトをマップHashMapを作成したい

。両方のオブジェクトは、StringまたはIntegerのいずれかです。

Java Genericsでは、事前に型を知っておく必要があるため、この問題は解決できません。それ以外の場合はキャストする必要があります。

正直に言うと、私はあなたが投稿コードで達成したいのか分からないが、あなたがHashMapを使用したい場合、あなたはこのようにそれを行うことができます。この場合

private final HashMap<String, Integer> left2Right = new HashMap<String, Integer>(); 
left2Right.put("one", 1); 
int numberOne = left2Right.get("one"); 

ますHashMapにはStringキーとInteger値があるため、値をキャストする必要はありません。異なる型を値として入れる場合は、すべての値のスーパータイプを使用する必要があります。このスーパータイプは、階層のルートであるObjectである可能性があります。しかし、そのような場合は、キャストする必要があります - 値のオブジェクトの種類がわからないためです。

private final HashMap<String, Integer> left2Right = new HashMap<String, Object>(); 
    left2Right.put("one", 1); 
    left2Right.put("two", new Date()); 
    // Because the compiler cannot know that type "one" might be, this isn't allowed and  you have to cast the value. It might be anything - in this example Date or Integer. 
    int numberOne = left2Right.get("one"); 

私は役立つことを望みます。

関連する問題