Menu

#7 Try/finally duplication confuses bytecode analyser

open
nobody
5
2004-11-05
2004-11-05
No

Consider the following program:

public class Demo
{
public void comparisonSameResult(Object o)
{
boolean isNull = true;
try
{
System.out.println(o.toString());
isNull = false;
}
finally
{
if (isNull) // *** this is line 13 ***
{
System.err.println("o is null");
}
}
}
}

Jlint version 3.0 warns:

Demo.java:13: Comparison always produces the same result.

javap -c -l gives:

Compiled from "Demo.java"
public class Demo extends java.lang.Object{
public Demo();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

LineNumberTable:
line 1: 0

public void comparisonSameResult(java.lang.Object);
Code:
0: iconst_1
1: istore_2
2: getstatic #2; //Field java/lang/System.out:Ljava/io/
PrintStream;
5: aload_1
6: invokevirtual #3; //Method java/lang/Object.toString:
()Ljava/lang/String;
9: invokevirtual #4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
12: iconst_0
13: istore_2
14: iload_2
15: ifeq 44
18: getstatic #5; //Field java/lang/System.err:Ljava/io/
PrintStream;
21: ldc #6; //String o is null
23: invokevirtual #4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
26: goto 44
29: astore_3
30: iload_2
31: ifeq 42
34: getstatic #5; //Field java/lang/System.err:Ljava/io/
PrintStream;
37: ldc #6; //String o is null
39: invokevirtual #4; //Method java/io/PrintStream.println:
(Ljava/lang/String;)V
42: aload_3
43: athrow
44: return
Exception table:
from to target type
2 14 29 any
29 30 29 any

LineNumberTable:
line 5: 0
line 8: 2
line 9: 12
line 13: 14
line 15: 18
line 13: 29
line 15: 34
line 18: 44

}

Thus it is apparent that the compiler (Apple's
"1.4.2_05", probably identical with Sun's of the same version
number) duplicates the finally block's body, and the comparison of
line 13 is performed in two places.

Discussion


Log in to post a comment.

MongoDB Logo MongoDB