首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android以非空类型返回Null

Android以非空类型返回Null
EN

Stack Overflow用户
提问于 2018-11-07 09:46:25
回答 3查看 4.2K关注 0票数 13

我有Dao来返回简单对象。如果对象不存在,房间返回null,但安卓应用程序不会崩溃。另外,如果我将该值赋值给非空变量,则应用程序中不会出现崩溃。

Dao:

代码语言:javascript
运行
复制
@Query("SELECT * FROM users WHERE id LIKE :id LIMIT 1")
abstract fun getById(id: Long): User

不是崩溃代码:

代码语言:javascript
运行
复制
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}")
        }
    }
}

我有两个问题:

  1. 房间怎么可能以非空变量的形式返回空值?
  2. 如何使赋值为null的非空变量的代码有,没有崩溃,
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-11-07 11:56:57

这都是关于Kotlin如何用Java代码处理边界上的空值。

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

例如:

代码语言:javascript
运行
复制
fun hello(who: String): Unit {
    println ("Hello $who")
}

变成了

代码语言:javascript
运行
复制
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:在Room bugtracker https://issuetracker.google.com/issues/112323132发现了类似的问题。Googler表示,这是有意的行为,如果您编写了可以返回空值的查询,那么您就有责任在dao接口中将其标记为可空。

票数 11
EN

Stack Overflow用户

发布于 2018-11-07 11:47:20

您没有得到NullPointerException的原因很简单: Room是一个Java,而不是Kotlin,所以它不知道您的User不应该是null。在与Java代码进行接口时,Kotlin引入了一些空检查来给出异常,但是由于您的接口是用Kotlin编写的,所以它假定这不会有问题,因此跳过检查。

我不是一个房间专家,但在谷歌搜索之后,我找不到一种方法来强迫Room检查空值。我看到了解决你的“问题”的两种方法:

  • 更改getById函数以返回User?
  • @Dao转换为Java接口,迫使Kotlin检查null。
票数 5
EN

Stack Overflow用户

发布于 2018-11-07 11:20:11

正如我所理解的,您生成的Dao类没有在Java代码中将返回值注释为@Nullable。

代码语言:javascript
运行
复制
@Override
public User getById(long id) {

应该是

代码语言:javascript
运行
复制
@Override
public @Nullable User getById(long id) {

因此,您没有看到警告

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53186937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档