3
class A <T> {

    private T field;
}

< ... extends ... >を使用して型パラメーターを強制的に制限付きの型にすることができることはわかっていますが、型パラメーター T を強制的に String、Integer、SomeClassB、SomeEnumC のいずれかにする方法を教えてください。他の何かでパラメータ化しますか?

A<SomeClassB> a = new A<SomeClassB>();

合法でしょう。

A<SomeClassX> a = new A<SomeClassX>();

違法でしょう。

私はすでにこれらのタイプをテストしようとしました

T instanceof SomeEnumC

クラスAのコンストラクターにありますが、非常に面倒です。

4

4 に答える 4

2

注:上記の@Jeffreyのコメントに同意します。この種の制限を行うことで有用な型情報を取得できるようには見えないため、これはあまり意味がないようです。ここであなたのユースケースが何であるか知りたいです。


T例のように、許容されるジェネリック型を無関係なクラスのリストに制限することはできません。superまたはを使用してのみジェネリック型を制限できますextends。つまり、特定の型のスーパータイプまたはサブタイプでなければなりません。

ただし、許可するクラスの数が限られているように見えるためT、それらすべてを列挙できるはずです。これが私が考えていることです:

public class A<T> {

  /**
   * Private constructor means only nested classes
   * can extend this class. We use this to limit the
   * types that can be used for T.
   */
  private A() { }

  /** Integer version of A */
  public static class IntA extends A<Integer> { }

  /** String version of A */
  public static class StringA extends A<String> { }

}

これで、静的インポートを使用して、必要なネストされたバージョンをインポートするかA<T>、次のようにすべてをインポートできます。import static A.*;

于 2013-11-09T23:19:18.363 に答える
1

クラス A を API の一部としてエクスポートすることを想定しています。これが、ジェネリック型パラメーターとして渡すことができる型を制限したい理由です。

クラス A を制限したいタイプのリストがわかっている (そして数がかなり少ない) 場合、回避策は、代わりにパッケージ プライベート インターフェイスを定義することです (これにより、パッケージの外部にあるクラスがインターフェイスを実装できなくなります)。

interface A <T> {
    T field;
}

次に、許可したい型の具象クラスを簡単に記述できます。他の誰もあなたのインターフェイスを実装できないため、許可するつもりのない型に基づいて誰かがクラスを作成する可能性はありません。

于 2013-11-10T00:22:23.073 に答える
0

コンパイル時に制限することはできませんが、わずかな調整で実行時に強制できます。

class A <T> {
    private T field;
    public A(Class<T> c) {
        if (c != String.class | c != Integer.class | c != SomeClassB.class | c != SomeClassC.class)
            throw new IllegalArgumentException();
    }
}
于 2013-11-09T23:44:49.647 に答える