Class オブジェクトが必要ですが、それが表すクラスが何であれ、強制的にクラス A を拡張し、インターフェイス B を実装したいと考えています。
できます:
Class<? extends ClassA>
または:
Class<? extends InterfaceB>
しかし、私は両方を行うことはできません。これを行う方法はありますか?
Class オブジェクトが必要ですが、それが表すクラスが何であれ、強制的にクラス A を拡張し、インターフェイス B を実装したいと考えています。
できます:
Class<? extends ClassA>
または:
Class<? extends InterfaceB>
しかし、私は両方を行うことはできません。これを行う方法はありますか?
実際、あなたはやりたいことをすることができます。複数のインターフェイスまたはクラスとインターフェイスを提供する場合は、ワイルドカードを次のようにする必要があります。
<T extends ClassA & InterfaceB>
sun.comのGenerics Tutorialを参照してください。具体的には、ページの下部にあるBounded Type Parametersセクションを参照してください。& InterfaceName
必要に応じて、必要なインターフェイスごとに forを使用して、実際には複数のインターフェイスを一覧表示できます。
これは、任意に複雑になる可能性があります。実証するには、JavaDoc の の宣言を参照してくださいCollections#max
。
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
なぜそんなに複雑なのですか?Java Generics FAQ: To preserve binary compatibilityで述べたように。
これは変数宣言では機能しないように見えますが、クラスにジェネリック境界を置くと機能します。したがって、やりたいことを実行するには、いくつかの手順を踏まなければならない場合があります。しかし、あなたはそれを行うことができます。クラスに一般的な境界を設定してから、次のようなことができます。
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
取得variable
するには、必要な制限があります。詳細と例については、Generics in Java 5.0の 3 ページを参照してください。<T extends B & C>
では、クラス名が最初に来る必要があり、インターフェースが後に続くことに注意してください。もちろん、リストできるクラスは 1 つだけです。
「匿名」型パラメーター (つまり、を使用するワイルドカード?
) では実行できませんが、「名前付き」型パラメーターでは実行できます。メソッドまたはクラス レベルで型パラメーターを宣言するだけです。
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}