私はいくつかの型Tのオブジェクトを取り込むジェネリックメソッドとその型を表すクラスを持っていたいと思います。最終的にはこれを使用してMap<Class<?>, Object>
を作成する予定です。そこでは、各クラスが正確に独自の型のオブジェクトにマップされることがわかります。私はこれをコンパイラに説得することはできませんが、できる限り多くのコードに対してコンパイル時の一般的な安全性を維持したいと思います。私は問題なくfoo
メソッドを書くことができ、そしてそれは私が欲しい署名を持っている、と私は正確に何種類のIを知っていれば、私はそれを使用することができますjavacはx.getClass()とxを一緒に使用するための適切なジェネリックを推論できますか?
public class Example {
public static <T extends Number> void foo(Class<T> c, T x) {
;
}
public static void bar(int x) {
foo(Integer.class, x);
}
public static void baz(Number x) {
foo(x.getClass(), x);
}
}
:ここで私はに実行している問題を実証する最小限の例です。 bar
のように、コンパイル時に持っているが、私はbaz
にしようとして、私は、任意の型のオブジェクトにそれを使用することはできません。baz
コンパイルされません、引用:
Example.java:11: error: method foo in class Example cannot be applied to given types;
foo(x.getClass(), x);
^
required: Class<T>,T
found: Class<CAP#1>,Number
reason: inferred type does not conform to lower bound(s)
inferred: CAP#1
lower bound(s): Number
where T is a type-variable:
T extends Number declared in method <T>foo(Class<T>,T)
where CAP#1 is a fresh type-variable:
CAP#1 extends Number from capture of ? extends Number
私はここでの問題を理解すると思います:x.getClass()
はClass<? extends Number>
を返します。<? extends Number>
をT
であるが、x
のタイプはNumber
であり、T
はNumber
である必要があります。私がこれを書いたとき、私はコンパイラがx.getClass()
とx
が全く同じT
を共有することを知っていることを期待していましたが、それはそれを知ることができません。
ここで私は何をしますか? foo
のようなものと、baz
のようなものを書くことができる方法はありますか?私はコンパイル時の安全性を放棄し、実行時にいくつかのキャストを行うべきですか? Map<Class, Object>
の私の最終目標に近づくための良い方法がありますか?
'バーを(int型x)'は、なぜそれが 'バー(数x)ではありません' – Tgsmith61591
これは 'クラスからfoo'の最初のパラメータ'かの変更をコンパイルすることができますか? 'を' Class extends T> 'に変更します。 –
rgettman
@rgettmanしかし、それは私が*許可したくない他のものを許可します。私の目標は、クラスとオブジェクトが同じであることを強制することです。スーパークラスをキーとして、またはそのサブクラスの1つをキーとしてオブジェクト参照をvalとして格納することはできません。 – amalloy