如何引用通用类型的变量?

时间:2019-11-16 23:46:08

标签: android kotlin android-room

我正在尝试为Room库实现“基本DAO”接口,以避免样板代码:

BaseEntity.kt

interface BaseEntity {
    val entityName: String
}

Note.kt

@Entity
class Note : BaseEntity {
    override val entityName: String = "note"
    ...
}

BaseDao.kt

interface BaseDao<T : BaseEntity> {
    @Query("SELECT * FROM ${T.entityName}")
    fun selectAll(): List<T>
    ...

}

NoteDao.kt

@Dao
interface NoteDao : BaseDao<Note> {
...
}

但是,表达式${T.entityName}无效。有办法吗?

1 个答案:

答案 0 :(得分:1)

我不认为您可以实现“基本DAO”界面。原因是 Room在编译时创建了每个DAO实现。因此,为什么收到消息 注释参数必须是编译时常量

例如,房间需要从注释中知道将哪些表列映射到哪些变量以及用于执行映射的方法,以便可以生成基础代码。

例如,如果Entity和Dao是:-

@Entity
class Note {

    @PrimaryKey
    var entityName: String = ""

}

@Dao
interface BaseDao {
    @Query("SELECT * FROM Note")
    fun selectAll(): List<Note>

}

然后底层生成的java将是:-

public final class BaseDao_Impl implements BaseDao {
  private final RoomDatabase __db;

  public BaseDao_Impl(RoomDatabase __db) {
    this.__db = __db;
  }

  @Override
  public List<Note> selectAll() {
    final String _sql = "SELECT * FROM Note";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfEntityName = CursorUtil.getColumnIndexOrThrow(_cursor, "entityName");
      final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final Note _item;
        _item = new Note();
        final String _tmpEntityName;
        _tmpEntityName = _cursor.getString(_cursorIndexOfEntityName);
        _item.setEntityName(_tmpEntityName);
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }
}