【问题标题】:Java entering an if statement that is falseJava 输入一个错误的 if 语句
【发布时间】:2011-11-03 03:18:00
【问题描述】:

我在这个程序中遇到了一个最奇怪的错误,在调试它时得到了确认。我有以下代码(归根结底是为了突出问题,当然):

BHFrame.java

public class BHFrame
{
  private boolean uSS;
  private StateSaver stateSaver;

  public BHFrame(boolean useInternalStateSaver)
  {
    //Init code

    uSS = useInternalStateSaver;

    //More init code
    System.out.println(uSS);
    if (uSS)
    {System.out.println("Entered 1");
      stateSaver = new StateSaver(title, false);
      stateSaver.addSaveable(getThis());
    }

    //More init code
    System.out.println(uSS);
    if (uSS)
    {System.out.println("Entered 2");
      try
      {
        stateSaver.loadState();
        stateSaver.putState(getThis());
      }
      catch (IOException ex)
      {
        alertUserOfException(ex);
      }
    }
  }
}

GUI.java

public class GUI extends BHFrame
{
  public GUI(boolean useInternalStateSaver)
  {
    super(useInternalStateSaver);
  }
}

Main.java

public class Main
{
  public static void main(String[] args)
  {
    GUI gui = new GUI(false);
  }
}

输出

false
false
Entered 2
Exception in thread "main" java.lang.NullPointerException
    at bht.tools.comps.BHFrame.<init>(BHFrame.java:26)
    at bhms.GUI.<init>(GUI.java:5)
    at bhms.Main.main(Main.java:5)

BHFrame 类是从调用此构造函数的子类扩展和运行的,但这实际上不应该影响此行为。问题是,当false 作为useInternalStateSaver 传递给构造函数时,第一个if (uSS) 被跳过,但第二个被输入。经过调试,我发现uSS 在整个运行时都是false,包括在第二个if 语句的行上,这里。 当条件返回 false 时,为什么 Java 会输入 if 语句? 在你问之前,我确实删除了 .class 文件并重新编译它,以防万一有一些残留代码弄乱它,但我得到了相同的结果。请放心,对uSS 变量的所有引用都会显示在此处。

解决方案


事实证明,这似乎是 NetBeans 7.1 Build 201109252201 中的一个错误,其中 IDE 没有正确地将新代码插入到已编译的 .class 文件中。该问题已通过在外部编译文件得到解决。 bug report 已提交。

【问题讨论】:

  • if 条件不会做出错误的决定。您的变量 uSS 必须在您的 //More init code 行中变为 true。
  • 您正在调试的代码和您发布的代码不同(并且您发布的代码由于您删除的位而无法编译)-因此问题可能是由于.每个人都在说你错了,因为你向我们展示的代码不可能像你所说的那样做。但也许你实际运行的代码可以做到这一点。
  • 如果您不使用uSS 并添加另一个私有布尔值并使用它会怎样 - 会发生什么?而且,如果 Java 作为优化,如果它们打开,请尝试关闭它们?当代码在调试器和 Netbeans 之外运行时会发生什么?
  • 您的示例不是自包含的。问题是我们没有人可以获取代码、编译它并重现问题。我理解您为什么不能这样做,但这也意味着我们实际上无法帮助您。您的代码看起来不错,但它不完整(所以我们一直假设问题出在我们看不到的代码中)并且它不是独立的(所以我们自己看不到问题)。你最好的办法是不断减少它,直到你得到一段显示问题的代码,并且只包含你可以发布的方法。其他任何事情都可能会继续在同一个圈子里转。
  • 这可能很愚蠢,但请尝试使用稳定版本的 Netbeans。由于我们都看不到问题所在,我们只能假设您尝试一下。

标签: java if-statement netbeans-7


【解决方案1】:

在您发布的代码中可能不是抛出该异常。

catch 语句不会捕获它,它只会捕获 IOException。

这是一个 NullPointerException,可以在任何地方发生。

您没有显示if 块中的代码实际上正在执行。在您的屏幕截图中,绝对有办法知道您的 if 块是否已输入。没有日志记录语句。

在各个点添加调试消息以准确查看正在发生的事情。或者,您知道,请查看第 26 行(在您发布的代码之前的方式)以了解您收到 NullPointerException 的原因。

【讨论】:

  • 但它不应该首先进入 if 语句。由于打印了“Enter 2”文本,这意味着该块已被执行。
  • +1 只是为了指出截图证明代码与错误输出不匹配
  • 另一个编辑将调试后的输出截图添加到第一个截图的下一行
【解决方案2】:

当机器上的 RAM 出现故障时,我曾见过这样的疯狂事情。您可能想运行 memtest86。

您也可以考虑删除所有项目类文件,然后进行构建。也许您更改了 Main.java,但它从未重新编译。我讨厌这种情况发生。

【讨论】:

  • 我指出我删​​除了所有.class 文件的问题,为什么坏的RAM 会影响这个boolean 值,但剩下的4294967288 字节却完全没问题?而且即使是这样,那是不是意味着下次它会运行良好,因为uSS 将存储在不同的地址中?
  • 如果您认为它不是 RAM,那么您对这种明显的非确定性行为还有什么其他解释?我负责的一个项目在全国部署了 15,000 个 JVM。我们会将某些机器部署到 JVM 无法正常运行的地方,以及其他软件出现的地方。更换这些机器上的 RAM 后,问题就消失了。 Memtest86 是免费的,所以试用它是免费的。唯一的另一种选择是您做错了什么,而您不知道那是什么。
  • 请不要在未阅读完整问题(包括原因)和接受答案的情况下发布此类 cmets
  • 是的,我在回复后看到了上面的答案。我不知道它可以这样添加。不确定我是否应该删除我的评论。即不知道网站的礼仪。
  • 感谢您的反馈,很抱歉我错过了。
【解决方案3】:

这只是一个猜测,因为我看不到您提到的代码,但我认为您在第二个 //More init code 段中定义了一个局部变量 uSS

一旦定义了一个与 instance 变量同名的 local 变量,它就会“隐藏”实例变量。最好用this 限定所有实例变量。

所以,尝试使用this. 来限定uSS 的所有上述访问... (this.uSS)

即使这不是问题,最好还是发布完整的代码。

HTH

【讨论】:

  • 另外,最好将实例变量标记为final。似乎应该如此。同样,如果没有其他任何内容,这将提供清晰度
  • 查看编辑;有一个屏幕截图显示我所声称的确实是正在发生的事情。我不是新手程序员;我知道当我创建变量时它们会做什么(这就是为什么不将类变量 uSS 称为 useInternalStateSaver:以保证我引用了正确的变量)
  • 另外,我不愿意发布完整的代码,因为它不仅受版权保护,而且非常广泛。如果我得到足够的需求,我会的,但我向你保证,这就是你需要看到的全部内容。
  • 附注我只是赞成你的问题,因为显然你正在努力与你的[怀疑]观众互动。我看到你也找到了解决方案。不错的一个
  • 它一无所获。正如我之前提到的,我不是新手程序员,uSS 在首次初始化后从未更改过,而且我每次都引用同一个变量。然而,正如大多数受访者所认为的那样,这并不是糟糕的编码,而是 IDE 调试器中的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 2022-12-08
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多