2011-02-01 3 views
5

上の一般的な制約を有界私は、次のような何かをする必要性を感じていた時に何回ありました。本質的には、マップの2つの引数で同じバウンドを使用します。Javaはフィールド

これは(残念なことに)不可能であり、クラス定義とメソッドシグネチャでのみ利用可能であることは分かっています。これは実際の例ではありません。私の質問は、なぜそれがフィールドで利用できないのですか?純粋にデザインの選択ですか、それとも何か技術的な理由がありますか?私は思ったことがあり、なぜそれが技術的な観点からは不可能であるかを知ることはできません。コンパイラが正しく動作させるためにはすべてがあり、実行時には一般的な情報は必要ありません。

答えて

1

<T>は、Aクラスではなく、1クラスを意味します。 オブジェクトがインスタンス化されると、TはこのONEクラスにバインドされます。

異なるインターフェイスを持つ2つのオブジェクト(異なるタイプを取得/返すために使用される)を同じコンテナに配置しようとしています。これはエラーです。なぜなら、コンテナ(地図)から取り出したときに、何を入れていたのか分かりません。

希望していた回答です。

編集:そこには、クラスに基づいてメンバーを保持するコンテナを持つことができ、各タイプのTの新しいマップを自動的に作成することができます。次に、アクセスするためにTが何であるかを知る必要があります。 一般的に、タイプ情報をもう必要としない場合は、それを投げ捨ててください。あなたがそれを行うならば、それを別のタイプのものと同じコンテナに入れておくことは、実用上の理由から、それを放棄します。

+0

@ランタイムで可能だったことに基づいてコンパイラがあなたの言語を入力しなくなった場合、「実行時には何の情報も必要ありません」。入力は制限です。 – mncl

+0

答えをありがとう。私はあなたが何を言っているかを見ていますが、これが役に立つと分かるところは、キーのジェネリックパラメータを知っていれば、まったく同じジェネリックバウンドのオブジェクトを返すことが保証できます。 – berry120

+0

オブジェクトの種類がわかっている場合は、オブジェクトをキャストします。しかし、もしあなたが(yのxインスタンス)あなたがそれを間違ってやっている可能性が高い場合。代わりに型を保存してください。 – mncl

0

次のよう?を使用することができます。

private List<? extends List> l = new ArrayList<List>();

私はこのことができます願っています。

+0

答えに感謝しますが、それは私が後にしたことではありません。私は基本的なワイルドカードをその方法で使用できることを知っていますが、私は複数のジェネリックパラメータにわたって全く同じバインド(質問では、T)をキャプチャします。私は "?extends Type"を2回使用することができますが、それは同じ境界を保証するものではなく、2つの異なるクラスでTypeを拡張することができます。 – berry120

1

変数mapをインスタンス化するとします。理論的には、次のような記述が必要です。

map = new HashMap<GenericClass1<String>,GenericClass2<String>>(); 

しかし、今私には意味がないは、どのような引数でputまたはgetメソッドが受け入れ/返されるのでしょうか? T?ええと... Tは何ですか? GenericClass1|2<String>?再び意味がありませんか?結局のところ、宣言にはStringが表示されません。だから私は本当に正しいインスタンス化とこの汎用変数の使用法はないと思います。

乾杯!

1

私のようなもののために憧れているかああ、:

private <T> Map<Class<T>, T> instanceCache; 

public <T> T getInstanceOf(Class<T> clazz) { 
    return instanceCache.get(clazz); 
} 

しかし、あなたが述べたように、それはJavaで完全に不可能です。上記のメソッド宣言は問題ありませんが、メソッドにキャストがないように変数を宣言する方法はありません。ジェネリックスを嫌っていて、あなたが進んでいるものの増え続けるリストにこれを追加するだけです。

関連する問題