会议室数据库查询返回null,在Kotlin中应为null安全

时间:2019-11-17 22:32:26

标签: kotlin android-room

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

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

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

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

但是'fun queryMaxServerDate():String'是否应该为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
}

1 个答案:

答案 0 :(得分:1)

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

,null安全性除外
  

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

     

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

     

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

     
      
  • 未初始化的此可用   构造函数在某处传递和使用(“泄漏”);
  •   
  • A   超类构造函数调用一个open成员,其实现在   派生类使用未初始化状态;
  •   
  • Java互操作:      
        
    • 尝试访问平台类型为null的成员;
    •   
    • 用于Java互操作的泛型类型具有不正确的可空性,   例如一段Java代码可能会将空值添加到Kotlin中   MutableList,表示应使用MutableList   与之合作;
    •   
    • 由外部Java代码引起的其他问题。
    •   
  •   

Null Safety

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

  @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。