"遇到未知类型"在Firebase GenericTypeIndicator中使用泛型类型时

时间:2016-07-02 14:01:09

标签: java android generics firebase firebase-realtime-database

我尝试创建具有泛型类的类,其中我创建函数来读取实体列表。我知道我有两种方法可以做到这一点:(#1)通过循环读取每个实体或(#2)直接创建实体地图。

第二种方式看起来更有效但不幸的是open不能使用泛型类型 - 当我在代码中使用它时会返回GenericTypeIndicator

IllegalStateException: Unknown type encountered: T

所以:

  1. 有没有办法直接将通用类型的实体读入地图? (#2)
  2. 或者只是在循环中读取实体时,它们在性能上没有任何显着差异(#1)?
  3. Map<String, T> entityMap =
        dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {});
    

    例如。数据:

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

1 个答案:

答案 0 :(得分:1)

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