会议室数据库查询返回空值(在Kotlin中应为空值安全) [英] Room database query returns null where it should be null-safe in Kotlin

查看:157
本文介绍了会议室数据库查询返回空值(在Kotlin中应为空值安全)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当数据库为空时,我有一个没有结果的查询.因此,NULL是正确的返回值.

I have a query that does not have a result, when the DB is empty. Therefore NULL is the correct return value.

但是,Android Studio中的编译器向我发出警告:
条件'maxDateTime!= null'始终为'true'.

However, the compiler in Android Studio gives me the warning:
Condition 'maxDateTime != null' is always 'true'.

如果我调试代码,则空检查会正确执行,因为该值实际上为空.

If I debug the code, the null check performs correctly as the value is actually null.

当我将接口重写为"fun queryMaxServerDate():字符串?"时(注意问号),编译器警告就会消失.

When I rewrite the interface to 'fun queryMaxServerDate(): String?' (notice the question mark), the compiler warning goes away.

但是'fun queryMaxServerDate():String'是否不应该导致编译错误,因为它可以为null?

But should not 'fun queryMaxServerDate(): String' result in a compilation error since it can be null?

@Dao
interface CourseDao {

    // Get latest downloaded entry
    @Query("SELECT MAX(${Constants.COL_SERVER_LAST_MODIFIED}) from course")
    fun queryMaxServerDate(): String

}


// calling function
/**
 * @return Highest server date in table in milliseconds or 1 on empty/error.
 */
fun queryMaxServerDateMS(): Long {
    val maxDateTime = courseDao.queryMaxServerDate()

    var timeMS: Long = 0
    if (maxDateTime != null) { // Warning: Condition 'maxDateTime != null' is always 'true'
        timeMS = TimeTools.parseDateToMillisOrZero_UTC(maxDateTime)
    }
    return if (timeMS <= 0) 1 else timeMS
}

推荐答案

由注释生成的基础代码是 java ,因此,按照:-

The underlying code generated by the annotation is java and thus the exception to null safety as per :-

Kotlin的类型系统旨在从中消除NullPointerException 我们的代码. NPE的唯一可能原因可能是:

Kotlin's type system is aimed to eliminate NullPointerException's from our code. The only possible causes of NPE's may be:

显式调用以抛出NullPointerException();的用法! 如下所述的运算符;

An explicit call to throw NullPointerException(); Usage of the !! operator that is described below;

关于某些数据不一致 进行初始化,例如:

Some data inconsistency with regard to initialization, such as when:

  • 未初始化的此可用 构造函数在某处传递和使用(泄漏");
  • A 超类构造函数调用一个open成员,其实现在 派生类使用未初始化状态;
  • Java互操作性:
    • 尝试访问平台类型为null的成员;
    • 用于Java互操作的泛型类型具有不正确的可空性, 例如一段Java代码可能会将空值添加到Kotlin中 MutableList,表示应使用MutableList 与之合作;
    • 由外部Java代码引起的其他问题.
    • An uninitialized this available in a constructor is passed and used somewhere ("leaking this");
    • A superclass constructor calls an open member whose implementation in the derived class uses uninitialized state;
    • Java interoperation:
      • Attempts to access a member on a null reference of a platform type;
      • Generic types used for Java interoperation with incorrect nullability, e.g. a piece of Java code might add null into a Kotlin MutableList, meaning that MutableList should be used for working with it;
      • Other issues caused by external Java code.

      无效安全

      例如在 CourseDao 中为 queryMaxServerDate()生成的代码将类似于:-

      e.g. the generated code for queryMaxServerDate() in CourseDao would be along the lines of :-

        @Override
        public String queryMaxServerDate() {
          final String _sql = "SELECT max(last_mopdified) from course";
          final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
          __db.assertNotSuspendingTransaction();
          final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
          try {
            final String _result;
            if(_cursor.moveToFirst()) {
              final String _tmp;
              _tmp = _cursor.getString(0);
              _result = _tmp;
            } else {
              _result = null;
            }
            return _result;
          } finally {
            _cursor.close();
            _statement.release();
          }
        }
      

      如您所见,没有提取数据(没有第一行)并且返回null.

      As you can see, no data extracted (no first row) and null is returned.

      这篇关于会议室数据库查询返回空值(在Kotlin中应为空值安全)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆