将泛型与 Firebase snapshot.getValue() 结合使用的最佳实践

2024-05-03

TL;DR:如何正确使用 Firebase DataSnapshot.getValue() 的泛型类?

用例:我想使用 Firebase 为我的所有实体(其中一堆)实现一个通用远程数据源类。当监听数据更改时,我想从 datasnapshot 获取值作为 E 类型的对象(其类型在其他地方确定),但我不知道它是否可以通过 Firebase 查询执行,如下所示:

public class GenRemoteDataSource<E extends SomeClass>
{
   //...
   public void onDataChange(DataSnapshot dataSnapshot)
   {
        E item = (E) dataSnapshot.getValue(); // <- unchecked cast and it doesn't work
        items.add(item);
   }
}

例如,我有一个扩展 SomeClass 的 Foo 类,并且带有 Foo 类的 GenRemoteDataSource 的实现将是:

public class Foo extends SomeClass{}

public class FooRemoteDataSource extends GenRemoteDataSource<Foo>
{
   //...
}

但 Firebase 会抛出运行时错误,因为它不会将 getValue() 强制转换为 Foo,而是尝试将 value 强制转换为上限 SomeClass。我很困惑为什么会发生这种情况:

Java.lang.ClassCastException: java.util.HashMap cannot be cast to com.example.app.SomeClass

请告知我应该如何使用类型安全来做到这一点(没有未经检查的强制转换)。谢谢。

EDIT下面的内容被证明是无关紧要的,请参阅通用类型指示器 https://firebase.google.com/docs/reference/android/com/google/firebase/database/GenericTypeIndicator

EDIT我也尝试过(盲目地尝试,值得一试)GenericTypeIndicator,

GenericTypeIndicator<E> mTypeIndicator = new GenericTypeIndicator<>();
E item = dataSnapshot.getValue(mTypeIndicator);

但它会抛出以下运行时错误。

com.google.firebase.database.DatabaseException: Not a direct subclass of GenericTypeIndicator: class java.lang.Object

TL;DR 我的解决方案,(引入了比语义上必要的更多的依赖性?)

public class GenRemoteDataSource<E extends SomeClass>
{
   //...
   private final Class<E> clazz;

   GenRemoteDataSource(Class<E> clazz)
   {
      this.clazz = clazz;
   }

   //...
   public void onDataChange(DataSnapshot dataSnapshot)
   {
        E item = dataSnapshot.getValue(clazz); // <- now is type safe.
        items.add(item);
   }
}

我最终只是通过构造函数注入向 getValue() 提供类定义。这是通过传递一个来完成的Class<T>到泛型类的构造函数中,并将其设置为 Firebase 的 getValue() 用作实例参数。如果有更好的解决方案,请发表评论,因为对我来说这似乎是多余的。谢谢你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将泛型与 Firebase snapshot.getValue() 结合使用的最佳实践 的相关文章

随机推荐