An example to use javap to analyze Java source code
I have the following source code in Java:
class Outer {
Nested nested;
Nested getNested() {
return nested;
}
}
class Nested {
Inner inner;
Inner getInner() {
return inner;
}
}
class Inner {
String foo;
String getFoo() {
return foo;
}
}
public class NullableTest {
public static Outer getInitializedOuter(){
Outer outer = new Outer();
outer.nested = new Nested();
outer.nested.inner = new Inner();
outer.nested.inner.foo = "Jerry";
return outer;
}
/* null pointer exception
private static void way0(){
Outer outer = new Outer();
System.out.println(outer.nested.inner.foo);
}*/
public static void way1(){
Outer outer = getInitializedOuter();
if (outer != null && outer.nested != null && outer.nested.inner != null) {
System.out.println(outer.nested.inner.foo);
}
}
public static void main(String[] args) {
//way0();
way1();
}
}


According to instruction list explanation in wiki:
If the current value is null, execution will go to code #41, which is directly return.


From the list above, we can also see another instruction ifnonnull. So here the interesting fact is, according to the analysis so far, the source code below:
if (outer != null && outer.nested != null && outer.nested.inner != null) {
System.out.println(outer.nested.inner.foo);
}
is actually compiled by Java as the execution approach below:
if (outer == null )
return;
if( outer.nested == null )
return;
if( outer.nested.inner == null)
return;
System.out.println(outer.nested.inner.foo);
The usage of LineNumber Table:
LineNumberTable is one of the optional attributes that holds metadata for debugging purposes. In this case, it specifies which offsets in the bytecode correspond to each line in the original source code. This is useful for printing more informative stack traces and for providing features like single step in the debugger. The example above illustrates the mapping relationship from byte code and original source code.