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

一个简单的例子教会您使用javap

阅读更多

javap是JDK自带的工具:

 

这篇文章使用下面这段简单的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();
    }
}

使用下面的命令行对NullableTest进行反编译,以java编译器生成的字节码:

javap -v NullableTest >c:\code\1.txt

 

查看方法way1()对应的字节码:

 

下面这个wiki包含了java字节码里每个指令的具体说明:

https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

 

下面对NullableTest反编译得到的字节码做一些说明:

0: invokestatic #42 // Method getInitializedOuter:()Ljava8/Outer;

代表静态方法getInitializedOuter的调用, Ljava8/Outer意思是该方法的返回类型是Outer

3: astore_0

将上述静态方法调用返回的outer引用存储到局部变量中,局部变量的id为0.

4: aload_0

因为在我前面的Java源代码中,我将静态方法返回的对象引用同null做了比较,因此使用指令aload_0将存储在代号为0的局部变量中的对象引用重新加载到栈上,此后才能和null做比较。

5: ifnull 41

这就是我在Java源代码里书写的IF分支。如果IF分支里检测的outer引用为null,则直接返回了。体现在字节码就是,如果ifnull为true,则跳转到第41行字节码,即直接返回。

 

如果ifnull不为true,则继续执行下去。又将outer引用加载到栈上。

从字节码的分析可以观察到一个有趣的现象,再次看看我们的IF语句。

Java编译时,编译器实际将其转换成了下面的写法:

if (outer == null )

return;

if( outer.nested == null )

return;

if( outer.nested.inner == null)

return;

System.out.println(outer.nested.inner.foo);

这个事实可以通过下图得到确认。

 

javap生成的字节码里的LineNumberTable也很有用。这张表里每行的line后面的数字代表Java源代码的序号,line XX冒号后面的数字代表字节码里每行指令的序号。看看下图中Java源代码和对应的字节指令在LineNumberTable中的映射关系。

 

LineNumberTable维护了Java源代码同字节指令的映射关系,确保了Java代码调试的顺利进行。

 

要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

 

 
 
分享到:
评论

相关推荐

    javap使用(1).docx

    `javap` 是 Java 开发工具包 (JDK) 中的一个重要工具,主要用于反编译 `.class` 文件中的字节码。通过 `javap`,开发者能够深入了解 Java 编译器是如何处理源代码并生成字节码的,这对于优化程序性能和理解 Java ...

    javap使用说明文档

    javap 是 JDK 中的一个命令行工具,主要用于对给定的 class 文件进行反编译,了解 Java 编译器内部的工作机制,并提高程序执行的效率。下面是 javap 的使用说明。 1. javap 的基本用法 javap 的基本用法是 javap ...

    javap写的完整记事本

    这款“javap写的完整记事本”是一个很好的学习资源,对于想要了解如何使用Java Swing构建桌面应用,尤其是涉及文本编辑功能的开发者来说,它可以提供宝贵的实践经验。通过阅读和分析源代码,你可以深入理解Java GUI...

    javap写的一个动态日历

    这个标题表明我们正在讨论一个使用Java编程语言编写的日历程序。`javap`在这里可能被误用,实际上`javap`是Java平台的标准工具,用于反汇编Java类文件,展示字节码和相关的元数据。在上下文中,可能是想指代使用Java...

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

    - **标志(flags)**:ACC_PUBLIC, ACC_SUPER 表示这是一个公共类,并且继承自一个父类(默认情况下所有类都继承自Object类)。 2. **常量池(Constant Pool)**:这部分包含了类定义时的所有常量信息,包括类名、字段...

    javap命令的使用技巧

    下面是一个简单的例子,演示了如何使用 javap 命令来反编译一个 class 文件。 首先,我们编写一个简单的 Java 类: ```java package com.thundersoft.metadata.test.kafka; import org.apache.kafka.clients....

    javap2p技术内幕.part2.rar

    javap2p 技术内幕javap2p 技术内幕javap2p 技术内幕javap2p 技术内幕

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

    `Javap`是Java开发工具包(JDK)中自带的一个命令行工具,专门用于分析Java字节码,帮助开发者理解类文件的内部结构。在这个话题中,我们将深入探讨如何使用`Javap`作为类分解器来解析和理解Java字节码。 首先,让...

    HelloWorld的javap -verbose HelloWorld 字节码初探

    标题中的“HelloWorld的javap -verbose HelloWorld”指的是在Java编程环境中,通过`javap`这个命令行工具来反汇编一个简单的“HelloWorld”程序,以深入理解字节码的工作原理。`javap`是Java Platform Debugger ...

    ndk开发实战javap签名篇

    标题“ndk开发实战javap签名篇”指向了一个针对使用NDK进行Android应用开发过程中的具体技术实践——使用javap命令来获取Java类的签名信息,并生成相应的C/C++头文件,这对于在C/C++代码中调用Java层的方法是必需的...

    javaP2P总结

    2. **IP与端口**:在Java P2P编程中,每个节点需要一个唯一的IP地址和端口号来标识其在网络中的位置。Java的`InetAddress`类用于处理IP地址,而`ServerSocket`和`Socket`类则用于管理和建立连接的端口。 3. **多...

    JavaP7架构师课程 JavaP7架构师课程

    JavaP7架构师课程

    Java的class文件结构介绍以及如何实现javap

    NULL 博文链接:https://bolinyang.iteye.com/blog/1830472

    javap-Tool:JAVA项目

    在`javap-Tool-master`这个压缩包中,很可能包含了一个关于如何使用`javap`工具的示例项目或教程。通过研究这个项目,你可以深入理解`javap`的用法,并学会如何在实际开发中运用它来提升你的编程技能。对于Java...

    JavaP2P技术内幕 part3

    JavaP2P技术基于Java语言,利用其跨平台特性,构建了一个去中心化的网络架构。在P2P网络中,每个节点既是服务提供者也是服务消费者,这与传统的客户端-服务器模型有着本质的不同。这种模式提高了网络的鲁棒性和效率...

    javap2p基于jxta

    标题“javap2p基于jxta”表明这个压缩包文件包含了一个使用JXTA库实现的Java P2P示例项目。这个项目可能是为了帮助开发者理解和学习如何利用JXTA进行P2P通信。通过分析和运行“myjxtademo”这个示例,我们可以深入...

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

    使用javap一个挑战是正确指定类路径。 由于SBT知道您项目的类路径,因此sbt-javap可以自动为您调用javap 。快速开始当前, sbt-javap已针对SBT 1.x发布。 要使用sbt-javap ,请将以下内容添加到project/plugins.sbt...

    JavaP2P技术内幕 part4

    P2P网络的一个核心优势是资源共享。节点可以共享文件、存储空间、计算能力等资源,这通常通过节点间直接的数据传输实现。 #### 3. 搜索与索引 为了高效地定位网络中的资源,P2P系统通常会包含搜索和索引机制。这些...

    eclipse配置javap命令的方法

    在Java开发环境中,Eclipse是一个广泛使用的集成开发环境(IDE),它提供了许多强大的功能来支持开发者的工作。然而,有时我们可能需要对Java字节码进行分析,这时就用到了`javap`命令,它是Java Development Kit ...

    用Java Socket实现一个简单的基于P2P范型的即时聊天系统。

    在本文中,我们将深入探讨如何使用Java的Socket编程来实现一个简单的基于P2P(Peer-to-Peer)范型的即时聊天系统。P2P网络架构允许每个节点既是客户端也是服务器,这种模式使得数据传输更加分散,提高了系统的可扩展...

Global site tag (gtag.js) - Google Analytics