【问题标题】:Java transient keyword and nullJava 瞬态关键字和 null
【发布时间】:2015-04-12 16:46:05
【问题描述】:

我正在使用 Intellij IDEA,以下代码会生成警告:“Expression testObj might evaluate to null but is returned by the method declared as @NotNull (at line 16)

package com.dlp;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class TestCase {
    @Nullable
    private transient Object testObj = null;

    @Nonnull
    public Object getTestObj() {
        if(testObj == null) {
            testObj = new Object();
        }

        return testObj; //Line 16
    }
}

仅当我将 testObj 标记为瞬态时才会发生这种情况。删除关键字会清除警告。瞬态和可空性之间是否存在一些我没有得到的交互,或者这只是 IDEA 中的一个错误?

【问题讨论】:

  • 唯一(在我脑海中)是显而易见的——如果一个可序列化的实例被反序列化,除非它被处理,否则它将为空
  • @jdphenix 但是该方法已经检查了该条件。虽然如果这个对象被反序列化,testObj 将是 null 是正确的,但同样适用于默认初始化为 null 的非瞬态字段。我已经将该字段标记为@Nullable。该字段如何变为空不应该是一个问题。奇怪的是,IDEA 认为 testObj 可以在 检查它不是之后立即为空。
  • 确实 - 我怀疑是错误。
  • 我认为出现错误的部分没有被您复制到这里。 IntelliJ 指的是具有 NotNull 注释的方法,但根据代码的定义,它可以返回 null。 20号线是哪条线?知道这会很有帮助。你没有复制的 NotNull 方法在哪里?
  • @HamedMoghaddam 我复制了一个默认的版权标头,将所有内容都向上移动了,并且我将我的 IDEA 设置为假设所有方法都是非空的,除非另有说明。我的 IDEA 也设置为带有 NotNull 的别名 javax.annotation.Nonnull,因此差异不是问题。我解决了这个问题。

标签: java intellij-idea transient


【解决方案1】:

可空性在编译器中非常严格。是的,您确实检查了 null,但存在一个问题,即您的代码可能在多线程上下文中使用。考虑这种情况:

这个块被执行:

    if(testObj == null) {
        testObj = new Object();
    }

当前线程被抢占,另一个线程出现并将testObj 设置为空。然后原来的线程再次激活并完成执行并为testObj返回null

编写此代码以避免空警告的正确方法如下:

public Object getTestObj() {
    Object tmpObj = testObj
    if(tmpObj == null) {
        tmpObj = new Object();
        testObj = tmpObj;
    }

    return tmpObj;
}

在这种情况下,您可以保证返回值永远不会为空。

当然,这是一个非常严格的极端情况,大多数程序永远不需要这种级别的安全性,但这就是编译器应该检查 null 的方式。

添加瞬态时 null 警告消失的事实似乎是 IntelliJ 错误。但是,上面建议的代码是处理字段可空性的正确方法。如果这对您来说太繁重,我建议避免在字段上添加空注释。

【讨论】:

  • 我认为您误读了我的问题。警告 only 在我使用瞬态关键字时发生。我知道线程会弄乱这个方法,在多线程上下文中做这样的事情需要 volatile 关键字或某种同步/内存屏障(我不完全确定你的解决方案是否会工作,由于内存缓存和java的内存模型)。奇怪的是,IDEA没有这个transient关键字非常开心,但它却开始变得不安。
  • 在我的最后一段中,我提到 with 瞬态关键字的行为可能是正确的,而没有它的行为很奇怪。
猜你喜欢
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
  • 2013-04-20
  • 2014-11-11
  • 2018-10-27
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多