3

List必要なことを実行する1つのメソッドを正常に記述した後(以下のサンプルを大幅に短縮)、を返すように制限されるのではMyEntityなく、代わりにリファクタリングしたいと思いList<SomeType extends MyParentEntity>ます。したがって、myを拡張するタイプのみを受け入れることができるはずですが、別MyParentEntityのタイプ(など)を指定することはできます。List<MyOtherEntity>List<MyAwesomeEntity>

短縮例:

 public static List<MyEntity> getFavList(Context context) {

        String prefKey = buildKey( new MyEntity() );
        List<MyEntity> entityList = new ArrayList<MyEntity>();

        SharedPreferences settings = context.getSharedPreferences(prefKey, 0);

        GSON gson = new GSON();
        MyEntity entity = gson.fromJson(settings.getString(0, null), MyEntity.class);

        entityList.add(entity);

        return entityList;
    }

私はたくさんグーグルで検索しましたが、コンパイラエラーなしでこれを機能させるための正しいアプローチを見つけられませんでした。解決策につながる指針をいただければ幸いです。

4

4 に答える 4

2

の具体的な実装に関する情報はMyParentEntity、メソッドparamsから取得する必要があります(戻り型から推測することはできません-ナンセンス)。したがって、パラメータを変更する必要があります。

私は試してみます:

public static <T extends MyParentEntity> List<T> getFavList(Context context, Class<T> clazz) {

        String prefKey = buildKey( clazz.newInstance() );
        List<T> entityList = new ArrayList<T>();

        SharedPreferences settings = context.getSharedPreferences(prefKey, 0);

        GSON gson = new GSON();
        MyEntity entity = gson.fromJson(settings.getString(0, null), clazz);

        entityList.add(entity);

        return entityList;
    }
于 2012-09-18T16:18:02.743 に答える
2

Classとを渡すオブジェクトを渡す必要がありますbuildKey

public static <T extend MyParentEntity> List<T> getFavList(
    Context context, Class<T> clazz, T key
) {

    String prefKey = buildKey(key);
    List<T> entityList = new ArrayList<T>();

    SharedPreferences settings = context.getSharedPreferences(prefKey, 0);

    GSON gson = new GSON();
    MyEntity entity = gson.fromJson(settings.getString(0, null), clazz);

    entityList.add(entity);

    return entityList;
}

(どうあるべきかわかりませんbuildKey。)

于 2012-09-18T16:33:36.320 に答える
1

Javaには型消去機能があるため(http://docs.oracle.com/javase/tutorial/java/generics/erasure.htmlを参照)、に与えられた型パラメータを簡単に取得することはできません。List<Something>

ただし、Javaには、型消去をだますことができる場所が2つあります。1つは、パラメーター化されたもののサブクラスを作成することです。このようなトリックは、GusavsだけでなくGusavsでも使用されていますTypeToken

以下の例を参照してください。

List<MyThing> l = gson.fromJson("[{}, {}]", new TypeToken<List<MyThing>>(){}.getType());

ここで、パラメーター化されたTypeTokenから派生する匿名クラスを作成していることに注意してください。前に説明したように、これにより、実行時List<MyThing>にTypeを保持できます。

詳細については、Gsonドキュメントのhttps://sites.google.com/site/gson/gson-user-guide またはStackOverflowのこちらをご覧ください:GSONまたはJavaの別のJSONライブラリを使用してリストを逆シリアル化する方法は?

PS:このリストの1つの要素を返したいだけだと思います(今のところ?)...?私の答えは、JSONからそのような要素のリストを実際にアンマーシャリングすることについてです-これは次に行うと思いますか?;-)「リスト内の単一の要素」だけを返したい場合は、Collections.singletonList()またはGuavaを使用ImmutableList.of()します。これらは不変であり(良いことです)、「通常のリスト」よりもメモリフットプリントがはるかに少ないためです。

乾杯、コンラッド

于 2012-09-18T17:19:08.043 に答える
0

@keyboardsurferがすでに指摘しているように、ジェネリックス情報は実行時に利用できないため、インスタンス化できるようにメソッドに具象クラスも提供する必要があります(とにかくそれをで使用するために必要になりますgson.fromJson())。

これを行うには、のを渡すだけでClassT参照T.classして作成できますnew T()。次の質問に詳細があります。Javaでジェネリッククラスをインスタンス化する

try/catch例(必要に応じて句を追加newInstance()):

public static <T extends MyParentEntity> List<T> getFavList(Context context, Class<T> clazz) {

    String prefKey = buildKey( clazz.newInstance() );
    List<T> entityList = new ArrayList<T>();

    SharedPreferences settings = context.getSharedPreferences(prefKey, 0);

    GSON gson = new GSON();
    T entity = gson.fromJson(settings.getString(0, null), clazz);

    entityList.add(entity);

    return entityList;
}

コンパイラは受け入れます

List<MyEntity> list = getFavList(ctx, MyEntity.class);
List<MyAwesomeEntity> list = getFavList(ctx, MyAwesomeEntity.class);
于 2012-09-18T16:08:03.543 に答える