其他分享
首页 > 其他分享> > Android Room将Null返回为Non-Null类型

Android Room将Null返回为Non-Null类型

作者:互联网

我有Dao返回简单的对象.如果对象不存在,则Room返回null,但Android应用程序没有崩溃.此外,如果我将该值分配给非null变量,则app中不会发生崩溃.

道:

@Query("SELECT * FROM users WHERE id LIKE :id LIMIT 1")
abstract fun getById(id: Long): User

没有崩溃的代码:

doAsync {
    val user: User = userDao.getById(999)   // user 999 not exist, userDao returns null
    uiThread {
        if (user == null) {
            Timber.d("user is $user")   // "user is null" in log
        } else {
            Timber.d("user is ${user.email}")
        }
    }
}

我有两个问题:

> Room怎么可能将Null值作为Non-Null变量返回?
>为null-Null变量赋值null的代码怎么可能没有崩溃?

解决方法:

这就是Kotlin如何使用Java代码处理边界上的空值.

如果将null从Java传递给需要非null值的Kotlin方法,则会出现异常.这是通过调用Kotlin编译器在方法开头添加的Intrinsics.checkNotNull函数来实现的.

例如:

fun hello(who: String): Unit {
    println ("Hello $who")
}

public final void hello(@NotNull String who) {
    Intrinsics.checkParameterIsNotNull(who, "who");
    String var2 = "Hello " + who;
    System.out.println(var2);
}

从Kotlin调用Java方法时添加了类似的检查.

但在你的情况下,你有Kotlin接口,它是由Room生成的Java实现.
所以Kotlin编译器无法添加检查,因为它无法控制所有接口实现.否则,它必须在每次调用Kotlin类或接口后添加检查,因为它可以用Java实现,这对性能有害.

UPD:在房间bugtracker https://issuetracker.google.com/issues/112323132发现了类似的问题.Googler说这是预期的行为,如果你编写了可以返回null值的查询,那么你有责任在dao接口中将其标记为可为空.

标签:android,crash,kotlin,android-room,kotlin-null-safety
来源: https://codeday.me/bug/20190607/1193972.html