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