0

私のコードでは、次のように型付きパラメーターを使用したいと考えています。

public static final ParameterDefinition<List<String>> NAMES
    = ParameterDefinition.build( List.class, CURRENCY );

これにより、後で次のように書くことができます。

List<String> names = object.get( NAMES );

ケースなしで。

しかし、それはコンパイルされません (Listと互換性がありませんList<String>)。

コンパイルするコードを取得できます:

@SuppressWarnings( { "unchecked", "rawtypes" } )
public static final ParameterDefinition<List<String>> NAMES
    = (ParameterDefinition) ParameterDefinition.build( List.class, "names" );

を取り除くにはどうすればよい@SuppressWarningsですか? List<String>.classJava 6 でシミュレートするにはどうすればよいですか?

注: 右側のコードはより複雑になる可能性があります (つまりbuild(List.class, String.class, "names" )、問題ありません) が、左側はそのままにしておく必要があります。

4

4 に答える 4

1

1 つの方法は、クラス/インターフェイスを拡張し、具体的な型パラメーターを定義するサブタイプを導入することですinterface StringList extends List<String>。メソッド内ではbuild、渡されたクラスのジェネリック型を取得できます。

呼び出しは次のようになります。

public static final ParameterDefinition<? extends List<String>> NAMES = ParameterDefinition.build( StringList.class, CURRENCY  );

確かに、これはあまりエレガントではありませんが、出発点になるかもしれません。これについてはもう少し考えてみます。:)

于 2013-08-16T14:16:54.093 に答える
0

「注意事項」より、build(?)の定義を変更できると思います。ParameterDefinitionが実際に型を知る必要があるかどうかも指定しませんでした。そうでない場合は、これでうまくいきます。

public static <X> ParameterDefinition<X> build(String name);

Javaがジェネリック型を推測するのがばかげているという理由だけでパラメーターが必要であるが、メソッドで使用されていない場合は、次のこともできます

public static <X> ParameterDefinition<X> build(Class<? super X> type, String name);

が型パラメーターを使用して値の型を保証する場合ParameterDefinition、結果が実際に であることを保証する引数は存在しないことに注意してくださいList<String>。それがおそらく、問題に対する簡単な解決策がない理由です。

気にしない場合は、次のことができます。

public static <X> ParameterDefinition<X> build(Class<X> type, String name) { ... }

@SuppressWarnings({"unchecked", "rawtypes"})
public static <X> Class<List<X>> listOf(Class<X> itemType) {
    return (Class) List.class;
}

static ParameterDefinition<String> = build(String.class, "name");
static ParameterDefinition<List<String>> = build(listOf(String.class), "keywords");

ここでの利点は、これらSuppressWarningsがライブラリ コードにあり、API ユーザーがそれらに対処する必要がないことです。

リストのすべての要素が文字列であることが実際に重要であり、実装が拡張可能であると想定している場合は、より複雑なアプローチが必要になります。

public interface ArgumentValidator<X> {

    boolean accept(Object o)

}

public static <X> ArgumentValidator<X> instanceOf(Class<X> type) { ... }

public static <X> ArgumentValidator<List<X>> listOf(Class<X> itemType) { ... }

public static <X> ParameterDefinition<X> build(ArgumentValidator<X> validator, String name) { ... }

public static <X> ParameterDefinition<X> build(Class<X> type, String name) {
    return build(instanceOf(type), name);
}

static ParameterDefinition<String> = build(String.class, "name");
static ParameterDefinition<List<String>> = build(listOf(String.class), "keywords");

アドバイス: の代わりにArgumentValidatorを使用してorg.hamcrest.Matcherください。

それは私が考えることができるすべてです。要件についてもう少し具体的に説明していただければ幸いです。

于 2013-08-17T12:27:21.840 に答える
0

ParameterDefinition はジェネリック クラスですか? つまり、次のように定義されますか?

public class ParameterDefinition<T>

またはそれ以外の何か

public class ParameterDefintion

その場合は を返すことができますが、そうでParameterDefintion<List<String>>ない場合は、領域内に配置する値を決定する必要があります<T>

ちなみに、 static メソッドに final を追加しても効果はなく、冗長です。私はそれを削除します。

ParameterDefinition が Generics パラメーターを受け取った後、次のように記述できます。

    public static final <X> ParameterDefinition<X> build(Class<X> clazz, String name) {
      ...
      return ...;
    }

そして、あなたはあなたが持っていたキャストさえ必要としません

(ParameterDefinition) ParameterDefinition.build( List.class, "names" );
于 2013-08-16T13:59:52.560 に答える