ジェネリック型のないクラスでは、次のような複雑なジェネリックフィールドを宣言します。
public class Client {
private Map<Class<T extends Serializable>, List<Consumer<S extends T>>> classToConsumerTry1;
private <T extends Serializable, S extends T> Map<Class<T>, List<Consumer<S>>> classToConsumerTry2;
}
問題はJavaコンパイラーが私にさせてくれません:)
したがって、私の質問は、クラスClientに型を追加せずにTとSを正しく導入する方法です。
私の目標は、Class
をSerializable
のサブタイプとし、Consumer
をClass
に対して選択したクラスのサブタイプにすることです。
できません。唯一の選択肢は、Client
クラス宣言でジェネリック型パラメーターを宣言することです。 Client
クラスにジェネリック型パラメーターがない場合、そのメンバーをジェネリックにすることはできません。クラスメンバーの宣言では、実際の型を使用する必要があります。
クラスメンバーの定義でそれらを使用できるように、どこかに型パラメーターを導入する必要があります。
型パラメーターの導入は、クラスレベルまたはメソッドレベルでのみ実行できます。あなたの場合、それはクラスレベルでなければなりません:
public class Client<T extends Serializable, S extends T> {
private Map<Class<T>, List<Consumer<S>>> classToConsumerTry1;
private Map<Class<T>, List<Consumer<S>>> classToConsumerTry2;
}
ただし、これは両方のメンバー(classToConsumerTry1
およびclassToConsumerTry2
)、T
およびS
は同じです。それらを異なるものにしたい場合は、これらの2つの値を2つの異なるクラスから取得する必要があります。これらのクラスは両方とも、別個の型パラメーターでパラメーター化されています。
フィールドで直接実行することはできませんが、ジェネリックメソッドによって型ポリシーを維持できます(ジェネリック以外のクラスにも存在できます)。
@SuppressWarnings("rawtypes")
private Map<Class, List> map;
public <T extends Serializable> void put(Class<T> key, List<Consumer<? extends T>> value) {
map.put(key, value);
}
@SuppressWarnings("unchecked")
public <T extends Serializable> List<Consumer<? extends T>> get(Class<T> key) {
return map.get(key);
}
思い通りのやり方はできません。ただし、Object
として設定してキャストできます。その他のハックな答えには、List
の_<? extends Serializable>
_の使用が含まれます(ただし、これは1つのextends
に対してのみ機能します)。次に、add()
アイテムまたは何かを実行する内部クラスお気に入り:
_private class Foo<T> {
T obj;
}
_
したがって、内部でobj
にアクセス/変更できます。