2014-11-11 1 views
0

나는 아파치 바틱과 관련이있는 일을하고있다. (이것은 적절하다고 생각하지 않지만 결코 알지 못한다.) 나는 이유를 알 수없는 이상한 행동을하고있다.Java가 "if"문을 Netbeans에서 감시하는 경우에만 트리거되는 이유는 무엇입니까?

코드의 다음 비트는 텍스트 행의 높이를 계산하는, 그래서 올바른 위치에서 다음 줄을 시작할 수 있습니다

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)의 값을 보면 결코 null로 표시되지 않습니다. 실제로 코드가 else으로 떨어질 때에도 if 조건의 정확한 진술에 시계를 적용하면 true으로 일관되게 평가됩니다. 기발한거야.

그러나 if ( runaci.getAttribute(TextAttribute.SIZE) != null) 줄에 중단 점을 배치하면 true으로 평가되므로 if ... else 블록의 첫 번째 절반으로 넘어갑니다. 브레이크 포인트를 꺼내면 else쪽으로 돌아갑니다.

JVM 최적화와 같은 다소 기발한 비트인가, 아니면 제한적인 최근 자바 경험으로 인해 나에게 준비되지 않은 일종의 평가 우회 버그가 있습니까?

편집 추가 : 현재 실행중인 IDE/디버거에서 문제가 제안되었지만 컴퓨터를 다시 시작하고 모든 항목을 정리/다시 작성한 후 새 문제가 발생하면 같은 문제가 나타납니다.

+1

비슷한 문제가 있었는데 대개 코드를 다시 입력하고 IDE/컴퓨터를 다시 시작하면 문제가 해결됩니다. – luisluix

+0

Luis가 포인트를가집니다. 나는 깨끗하게하고 짓고, 행동이 사라지는 지 확인하십시오. 그렇지 않으면 디버거 대신 로깅을 시도하십시오. 때로는 디버거 자체를 연결하여 발생하는 타이밍 문제 또는 기타 문제가있을 수 있습니다. – markspace

+0

때로는 (버그가있는) 디버거로 나에게 일어난 일이 있습니다. 그런 다음 런타임시 발생하는 상황을 파악하기 위해 일부 로깅을 수행합니다. 나는 Swing/AWT 쓰레드 대 디버거 인터셉터를 가지고 있다고 생각한다. – PeterMmm

답변

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; 
     } 
    } 

아마 좋은 정책은 아마도이 반복 평가를 필요로 같은 방법으로 반복 호출을 방지하기위한 몇 가지 최적화의 부작용입니다.

관련 문제