java - 在 Firebase GenericTypeIndicator 中使用泛型类型时为 "Unknown type encountered"

标签 java android generics firebase firebase-realtime-database

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

第二种方法看起来更有效,但不幸的是 GenericTypeIndicator 不适用于泛型类型 - 它返回 IllegalStateException: Unknown type encountered: T 当我在代码中使用它时:

Map<String, T> entityMap =
    dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {});

所以:

  1. 有什么方法可以将通用类型的实体直接读取到 map 中吗? (#2)
  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/

相关文章:

java - 为什么无法从 firebase 扫描数据

java - 用 Java 显示 GUI 组件

java - Hadoop/Mapreduce Reducer 不工作

android - 在 TabLayout 中禁用标签

android - 如何在Android Gradle中为每个构建变体设置packageNameSuffix?

java - 必需的 ? 类型捕获,提供 T

objective-c - 为什么通用 NSDictionary 不警告我键入错误的键插入/分配?

java - 如何在 RAD 管理控制台中更改 Web 领域设置

android - 查询 packageManager 以处理 Intent 时 GET_INTENT_FILTERS 和 MATCH_DEFAULT_ONLY 之间的区别

java - Java是如何解决这个untyped generic Method的呢?