我尝试创建具有通用类型的类,我在其中创建函数来读取实体列表。我知道我有两种方法可以做到这一点:(#1) 通过循环读取每个实体或 (#2) 直接创建实体映射。
第二种方法看起来更有效,但不幸的是 GenericTypeIndicator
不适用于泛型类型 - 它返回 IllegalStateException: Unknown type encountered: T
当我在代码中使用它时:
Map<String, T> entityMap =
dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {});
所以:
- 有什么方法可以将通用类型的实体直接读取到 map 中吗? (#2)
- 或者只是在循环中读取实体时它们在性能上没有任何显着差异(#1)?
public class SomeClass<T extends KeyEntity> {
private final Class<T> mGenericClass;
private final String mRefKey;
public SomeClass(Class<T> clazz, String refKey) {
mGenericClass = clazz;
mRefKey = refKey;
}
public class KeyEntity {
private String mKey;
public KeyEntity() {}
public String getKey() {
return mKey;
}
public void setKey(String key) {
mKey = key;
}
}
public interface EntityListListener<T> {
abstract public void onEntityListLoaded(List<T> entity);
}
public void loadAll(final EntityListListener<T> entityListListener) {
DatabaseReference dbRef = FireDbUtils.getReference(mRefKey);
dbRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<T> entityList = new ArrayList<>((int) dataSnapshot.getChildrenCount());
// #1 - read each entity in a loop
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
T entity = dataSnapshot.getValue(mGenericClass);
entity.setKey(childSnapshot.getKey());
entityList.add(entity);
}
// #2 - read all entity into a map
// GenericTypeIndicator doesn't like generic type
// if used, it returns "IllegalStateException: Unknown type encountered: T"
Map<String, T> entityMap
= dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {});
for (Map.Entry<String, T> pair : entityMap.entrySet()) {
T entity = pair.getValue();
entity.setKey(pair.getKey());
entityList.add(entity);
}
entityListListener.onEntityListLoaded(entityList);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
例如。数据:
{
carList: {
carKey1: {
name: "wife car"
},
carKey2: {
name: "my best car in the world ever"
}
},
garageList: {
garageKey1: {
name: "house garage"
},
garageKey2: {
name: "top secret garage under main garage"
}
}
}
最佳答案
使用ParameterizedType寻找泛型类对象
ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
//all generic classes
Type[] args = type.getActualTypeArguments();
Class<T> genericClass = (Class<T>) args[0];
T entity = dataSnapshot.getValue(genericClass);
关于java - 在 Firebase GenericTypeIndicator 中使用泛型类型时为 "Unknown type encountered",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38160980/