【问题标题】:Java: null comparison always yields false: incorrect warning?Java:空比较总是产生错误:不正确的警告?
【发布时间】:2011-02-25 08:49:48
【问题描述】:

有趣的情况。我有一段代码创建了几个 ZipOutputStreams。在我考虑写任何东西之前作为安全检查,我检查我的输出流是否已正确初始化:

ZipOutputStream countStream = null;
File countFile = null;
// other files

try {
    countFile =
    new File(savePath.getCanonicalPath() + savePath.separator + outputTag
        + "_COUNT_OUTPUTS.zip");
    // other files
} catch (Exception e) {
    outputLog.add("UNABLE TO FIND SAVE PATH");
    return util.FILE_INVALID;
}

try {
    // prepare outputs
    if (countFile.exists() == true) {
    countFile.delete();
    } else {
    }
    countStream = new ZipOutputStream(new FileOutputStream(countFile));
    // other files
} catch (Exception e) {
    e.printStackTrace();
    outputLog.add("UNABLE TO CREATE OUTPUT FILES");
    return util.FILE_SAVE_FAIL;
}

if (countStream == null) {
    outputLog.add("UNABLE TO CREATE OUTPUT FILES");
    return util.FILE_SAVE_FAIL;
} else {
}

我没有特别看出这段代码的问题出在哪里,但它会在 null 测试中引发警告:“Null 比较总是产生 false:变量 countStream 在这个位置不能为 null”。据我所见,我将一个变量初始化为 null,然后尝试创建输出流,但不能保证会发生。忽略警告很容易,但我更想知道编译器是如何得出保证成功创建 countStream 的结论

K.巴拉德

【问题讨论】:

  • 如果 countstream 不为 null,它将返回 false。这有什么问题?
  • 您的错误消息指的是 timeStream 而不是 countStream。这是复制粘贴错误吗?
  • 顺便说一句,您应该在 try catch 中添加一个 finally 块,以将 ZipOutputStream 关​​闭以关闭它(调用 close() 方法)。
  • 顺便说一句:if (countFile.exists() == true) 中的== true 部分是多余的
  • @Richard:很好,是的,我有几个拉链,都带有相同的警告。

标签: java zip warnings outputstream


【解决方案1】:

编译器能够看到你在那里不能为空,因为:

  1. 在您的 try 中,您已经初始化了它 (countStream = new ....) 并且
  2. 在您的 catch 中,您已“return”退出该方法。

因此,代码“if (countStream == null)”只有在将countStream初始化为非空ZipOutputStream后才能通过正常流程获得。

【讨论】:

  • 这是编译器可以进行一些出色的路径检查的情况之一。正如回答者声称的那样,错误只是“这里不能为空”。您将答案误解为“空比较总是返回错误”。 (我不知道 Kelindil 对此是否足够清楚——也许太客气了 :))
  • 我怀疑是这样的。这是说我只是过于谨慎,而且 FileOutputStream 和 ZipOutputStream 足够安全,不需要比 try-catch 块进行更多检查?
  • 一个“new ...”实例化,无论你调用什么构造函数,在哪个类上,都不能返回null。它可以在各种异常中失败,但不能为空。因此这个空检查确实是多余的:你要么将它实例化为一个非空值,要么因为异常而从方法中失败,或者通过你的catch从方法中返回。
  • 感谢您澄清这一点。我对流及其包装仍然有些缺乏经验,并且一直忘记将它们视为对象
【解决方案2】:

当没有Exception时,变量countStream不会为null。当出现异常时,你return util.FILE_SAVE_FAIL 并不会进行空检查。因此,无论何时执行 null 检查,结果都将始终为 false。

稍微正式一点:没有任何代码路径可以让执行到达您的空检查,导致在执行检查时countStream 为空。

【讨论】:

    【解决方案3】:

    我从这段代码中了解到 countStream 为空,这就是为什么它发出警告“空比较总是产生错误”

    如果您调试,您会发现此代码总是转到 else 部分,因为 if (countStream == null) { 条件未通过。

    【讨论】:

    • Ummm ...编译器说该值是 NEVER null
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    相关资源
    最近更新 更多