`
JerryWang_SAP
  • 浏览: 964937 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

使用javap分析Java字节码的一个例子

阅读更多

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

Get de-assembled byte code via javap:

 

 

Navigate to the part for method way1():

 

 

According to instruction list explanation in wiki:

0: invokestatic #42 // Method getInitializedOuter:()Ljava8/Outer; Call static method getInitializedOuter, whose return type is Outer 3: astore_0 Store returned Outer reference to local variable with id 0 4: aload_0 Since in Java source code, the reference outer will be compared against null via outer != null, so here aload_0 loads the reference stored in local variable #0 to stack. 5: ifnull 41 If the current value is null, execution will go to code #41, which is directly return.

 

 

or else continue to execute from #8: aload_0 to fetch outer into stack again. Why repeated call a_load_0 for loading outer reference is needed here? Again check the instruction list table:

 

 

For instruction ifnull, the value in the stack before executed is value, value is gone after ifnull is executed.

 

 

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.

When change way1 from public to private, in javap output you cannot find byte code for way1() itself any more.

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

0
1
分享到:
评论

相关推荐

    使用类分解器Javap分析Java字节码

    NULL 博文链接:https://shansun123.iteye.com/blog/658120

    javap使用(1).docx

    如何使用javap反编译字节码

    HelloWorld的javap -verbose HelloWorld 字节码初探

    NULL 博文链接:https://josephmok.iteye.com/blog/813774

    ByteCode Outline

    在遇到一些小问题的时候我们经常会使用Javap反编译取得字节码来分析,虽然Javap能完成这个工作,但是有两个缺点,一方面操作麻烦,需要很多步骤,一方面没有文档注释,对新手来说看起字节码来比较麻烦。 这里推荐...

    Java运行原理 javap命令运行结果

    Java运行原理 javap命令运行结果

    eclipse.BytecodeOutline插件

    在遇到一些小问题的时候我们经常会使用Javap反编译取得字节码来分析,虽然Javap能完成这个工作,但是有两个缺点,一方面操作麻烦,需要很多步骤,一方面没有文档注释,对新手来说看起字节码来比较麻烦。这里推荐一个...

    java开源包8

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    sbt-javap:直接从SBT控制台运行Javap

    Java提供了javap工具来反汇编和检查Java字节码。 这使作者可以查看其代码如何在较低级别上运行,了解如何对高级Scala概念进行编码以及潜在地发现性能问题。 使用javap一个挑战是正确指定类路径。 由于SBT知道您项目...

    javaclass和源码-deep-in-jvm:简单的借助jdk中的内置工具帮助我们对比Java源码和生成的字节码以及探究Class文件字节

    java class和源码 deep-in-jvm ...运行javap分析Class文件字节码 javap -verbose Main > Main.bytecode 分析包含内部类的源码编译出的Class文件 javap -verbose 'Main$Box.class' > 'Main$Box.bytecode'

    javap使用说明文档

    源文件 ---javac编译--> 字节码文件. 字节码文件 --javap反编译--> 源文件.

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java-class-quick-look:快速查看插件,将Java类文件显示为字节码

    这是一个快速查看插件,可让您将Java .class文件预览为字节码。 它使用javap -c命令。 要求 苹果系统 已安装Java 安装 编译目标并将二进制文件复制到/Library/QuickLook或~/Library/QuickLook 。

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java开源包4

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包11

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包101

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包6

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    jad- java反编译软件

    一个类似于javap的java反编译工具,运行速度快,据说Front End Plus、mDeJava、Decafe Pro、Cavaj Java Decomplier、DJ Java Compiler、NMI's Java Class Viewer等反汇编工具都以jad作为核心引擎,只是在jad内核的...

    java开源包9

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包5

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

Global site tag (gtag.js) - Google Analytics