[英]How to refactor a method to a generic one accepting only a subset of types?
成功后寫一個方法,它做什么它應該(縮短許多樣品下面)我想重構它不局限於返回一個List
的MyEntity
,而是一個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.