簡體   English   中英

如何將方法重構為只接受類型子集的泛型方法?

[英]How to refactor a method to a generic one accepting only a subset of types?

成功后寫一個方法,它做什么它應該(縮短許多樣品下面)我想重構它不局限於返回一個ListMyEntity ,而是一個List<SomeType extends MyParentEntity> 所以它應該只能接受那些擴展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;
    }

我google了很多,但我沒有找到正確的方法來使這項工作沒有任何編譯器錯誤。 我很感激能夠找到解決方案的任何指針。

有關MyParentEntity具體實現的信息必須從方法參數中獲取(不能從返回類型推斷 - 無意義)。 所以你必須修改參數。

我會嘗試:

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;
    }

您將需要傳遞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應該是什么。)

由於Java有類型擦除(在這里閱讀http://docs.oracle.com/javase/tutorial/java/generics/erasure.html ),你將無法輕易獲得給出的類型參數List<Something>

在Java中有兩個地方可以欺騙類型擦除。 一種是通過創建已經參數化的東西的子類。 這種技巧被Guava和Gsons 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:我看到你只想在這個列表中返回一個元素(現在?)......? 我的答案是關於從JSON實際解組這些元素列表 - 我猜你接下來會做什么? ;-)如果你只想返回“列表中的單個元素”,使用Collections.singletonList()或Guava的ImmutableList.of()因為它們是不可變的(一件好事)並且具有比“正常名單“。

干杯,康拉德

正如@keyboardsurfer已經指出的那樣,泛型信息在運行時是不可用的,所以你也應該為方法提供具體類以便能夠實例化它(無論如何你都需要它在gson.fromJson()使用它) 。

要做到這一點,只需傳遞Class of T ,這樣就可以引用T.class並創建new T() 以下問題有更多細節: 在Java中實例化泛型類

例如(根據需要為newInstance()添加try/catch子句):

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM