我正在做一些与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 /调试器出现问题,但在重新启动计算机并清理/重建所有内容后的新一天,同样的问题就会出现。
答案 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;
}
}
在任何情况下都可能以这种方式运作的良好政策 - 可能这是一些优化的副作用,旨在防止重复调用需要重复评估的相同方法。