为什么我的Java" if"如果我在Netbeans上有一块手表,只会触发声明吗?

时间:2014-11-11 16:25:35

标签: java if-statement netbeans

我正在做一些与Apache Batik有关的工作(不要认为这是相关的但你永远不知道)而且我遇到了一些奇怪的行为,我无法弄清楚原因。

下面的代码是计算一行文本的高度,因此它可以在正确的位置开始下一行:

protected double paintTextRun(TextRun textRun, double x, double y, int lineCount, EMFGraphics2D g2d) throws IOException 
{
     AttributedCharacterIterator runaci = textRun.getACI();
     char c = runaci.first();
     TextPaintInfo tpi = (TextPaintInfo) runaci.getAttribute(PAINT_INFO);
     if ( tpi == null || !tpi.visible )
     {
         return y;
     }
     setFont(runaci, g2d);
     g2d.setPaint(tpi.fillPaint);
     g2d.writeString(getTextFromACI(runaci, x, y);

     if (  runaci.getAttribute(TextAttribute.SIZE) != null )
     {
        y+= (float)runaci.getAttribute(TextAttribute.SIZE);
     }
     else if ( textRun.getLayout().getBounds2D() != null )
     {
         Double height = textRun.getLayout().getBounds2D().getHeight();
         if ( height != null )
         {
            y+=height/lineCount;
         }
    }
    return y;
    }

让我感到困惑的是,当我在y+= (float)runaci.getAttribute(TextAttribute.SIZE);行上放置断点时,它永远不会被触发,条件总是落到该语句的else侧。然而,如果我在Netbeans中观察runaci.getAttribute(TextAttribute.SIZE)的值,它似乎永远不会为空。实际上,即使代码落到if,将监视放在true条件的确切语句上也会始终评估为else。这很古怪。

但是,如果我在if ( runaci.getAttribute(TextAttribute.SIZE) != null )行放置一个断点,它会计算为true,因此我会进入if ... else块的前半部分。取出断点,然后返回else侧。

这是一种奇怪的JVM优化还是存在某种评估绕过错误,我最近的Java经验让我没有做好准备?

编辑添加:注释表明当前正在运行的IDE /调试器出现问题,但在重新启动计算机并清理/重建所有内容后的新一天,同样的问题就会出现。

1 个答案:

答案 0 :(得分:0)

我没有为什么,但是如果我将runaci.getAttribute(TextAttribute.SIZE)调用的结果指定为变量,它的行为与人们预期的一样。

  Object textSize = runaci.getAttribute(TextAttribute.SIZE);
  if (  textSize != null )
     {
        y+= (float)textSize;
     }
     else if ( textRun.getLayout().getBounds2D() != null )
     {
         Double height = textRun.getLayout().getBounds2D().getHeight();
         if ( height != null )
         {
            y+=height/lineCount;
         }
    }

在任何情况下都可能以这种方式运作的良好政策 - 可能这是一些优化的副作用,旨在防止重复调用需要重复评估的相同方法。