前言:
如今朋友们对“javacontentpane”可能比较珍视,咱们都想要知道一些“javacontentpane”的相关内容。那么小编也在网上汇集了一些关于“javacontentpane””的相关文章,希望大家能喜欢,兄弟们一起来学习一下吧!1.前言
在《【编译引擎】学习阅读Class文件结构(16进制版)》中,我们一起直接阅读了Class文件的16进制版本。
虽然这种方式可以帮助我们深刻理解Class文件结构,但如果您从事的是应用软件开发(而不是编译器相关工作),这样就比较低效了。
今天我们就来看看JVM提供的javap,如何提升我们解读Class结构的工作效率。
2.javap2.1.命令行学习方法
最好的学习资源就是官方文档:
在这里,我们可以获得最全面的javap使用指导。
2.2.命令行详解2.2.1.javap的命令行结构
javap [options] classfiles...
[options]:javap的命令行选项
classfiles:是我们需要反汇编的一个或多个类文件。
2.2.2.最常用的options
实战中,比较常用的options是输出所有显示所有类和成员、输出类的附件信息(如:堆栈大小、局部变量数量和方法的参数)
javap -v -p Test.class
其中,
-v:输出类的附件信息(如:堆栈大小、局部变量数量和方法的参数)-p:显示所有的类和成员2.2.3.梳理options
在官方文档中,javap的options很多,笔者做了这样的归类:
与类有关的options:
-l:打印行和局部变量表
-package:显示程序包/受保护的/公共类和成员 (默认)
-public:只显示公共类和成员
-protected:只显示受保护的和公共的类和成员
-p -private:显示所有的类和成员
-s:打印内部类型签名
-constants:显示static final常量
-c:打印类中每个方法的反汇编代码,例如,组成Java字节码的指令
-v,-verbose:打印堆栈大小、局部变量数量和方法的参数
与JVM有关的options:
-classpath <path>,-cp <path>:指定javap命令用于查找类的路径。覆盖默认的CLASSPATH环境变量 -bootclasspath <path>:指定加载引导类的路径。默认情况下,引导类是实现位于jre/lib/rt.jar和其它几个jar -extdir dirs:覆盖扩展类的位置。扩展的默认位置是java.ext.dirs的值 Joption:将指定的选项传递给JVM(JVM的options详见java命令文档) eg: javap -J-version javap -J-Djava.security.manager -J-Djava.security.policy=MyPolicy MyClassName -sysinfo:显示正在处理的类的系统信息(路径、大小、日期、MD5哈希值)
2.2.4.javap的形和神
前面解读了javap的命令行手册,这些只能算作javap的形,也比较好掌握,我们看看官方文档的javap输出的例子:
Compiled from "HelloWorldFrame.java"public class HelloWorldFrame extends javax.swing.JFrame { java.lang.String message; public HelloWorldFrame(); Code: 0: aload_0 1: invokespecial #1 // Method javax/swing/JFrame."<init>":()V 4: aload_0 5: ldc #2 // String Hello World! 7: putfield #3 // Field message:Ljava/lang/String; 10: aload_0 11: new #4 // class HelloWorldFrame$1 14: dup 15: aload_0 16: invokespecial #5 // Method HelloWorldFrame$1."<init>":(LHelloWorldFrame;)V 19: invokevirtual #6 // Method setContentPane:(Ljava/awt/Container;)V 22: aload_0 23: bipush 100 25: bipush 100 27: invokevirtual #7 // Method setSize:(II)V 30: return public static void main(java.lang.String[]); Code: 0: new #8 // class HelloWorldFrame 3: dup 4: invokespecial #9 // Method "<init>":()V 7: astore_1 8: aload_1 9: iconst_1 10: invokevirtual #10 // Method setVisible:(Z)V 13: return}
不了解JVM字节码的程序猿依然看不懂,这些就是javap的神。
这就好像辟邪剑法与辟邪剑谱的关系。
接下来,我们就来解读一下javap的输出结果——字节码。
3.javap输出结果解读3.1.字节码的基础知识
为了便于不太了解JVM字节码的程序猿更快进入下一章节,我们简单回顾和小结一下字节码的知识:
STEP1.我们通过java命令,将.java文件转化为.class文件(也就是字节码)STEP2.字节码文件本身是什么呢?我们可以用16进制编辑器打开它
字节码文件本身就是一串字节流。
STEP3.为了看的更加清楚一些,我们将有关联的字节用同一种颜色着色:
如果您做过网络协议的开发,会发现字节码(字节流)与协议栈(如:ModBus)的逻辑很类似,几个字节为一组表达一个信息。
STEP4.抽象一下上述着色字节流,我们可以将Class文件结构抽象如下
字节码基础属性
常量池:占据字节码文件最大的篇幅
类的基本信息:包含类名的索引、类访问标识、父类名的索引、实现了多少接口等信息
字段列表:包含有多少字段,每个字段名的索引、访问标识等
方法列表:包含多少方法,每个方法名的索引、访问标识、方法的实现等
附加属性
3.2.通过示例代码,解读javap的输出
我们以一段示例代码,来解读javap的输出:
示例代码:javap输出
javap -v -p Demo2.classClassfile /C:/Demo2.class Last modified 2021-1-25; size 613 bytes MD5 checksum f7c661d99330a1eefb32b6429e5a48b4 Compiled from "Demo2.java" public class com.firelord.zsample.lang.jvm.frontcompiler.Demo2 minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #7.#21 // java/lang/Object."<init>":()V #2 = Fieldref #6.#22 // com/firelord/zsample/lang/jvm/frontcompiler/Demo2.field1:I #3 = Fieldref #23.#24 // java/lang/System.out:Ljava/io/PrintStream; #4 = String #25 // hello world #5 = Methodref #26.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V #6 = Class #28 // com/firelord/zsample/lang/jvm/frontcompiler/Demo2 #7 = Class #29 // java/lang/Object #8 = Utf8 field1 #9 = Utf8 I #10 = Utf8 <init> #11 = Utf8 ()V #12 = Utf8 Code #13 = Utf8 LineNumberTable #14 = Utf8 LocalVariableTable #15 = Utf8 this #16 = Utf8 Lcom/firelord/zsample/lang/jvm/frontcompiler/Demo2; #17 = Utf8 hello #18 = Utf8 i #19 = Utf8 SourceFile #20 = Utf8 Demo2.java #21 = NameAndType #10:#11 // "<init>":()V #22 = NameAndType #8:#9 // field1:I #23 = Class #30 // java/lang/System #24 = NameAndType #31:#32 // out:Ljava/io/PrintStream; #25 = Utf8 hello world #26 = Class #33 // java/io/PrintStream #27 = NameAndType #34:#35 // println:(Ljava/lang/String;)V #28 = Utf8 com/firelord/zsample/lang/jvm/frontcompiler/Demo2 #29 = Utf8 java/lang/Object #30 = Utf8 java/lang/System #31 = Utf8 out #32 = Utf8 Ljava/io/PrintStream; #33 = Utf8 java/io/PrintStream #34 = Utf8 println #35 = Utf8 (Ljava/lang/String;)V { private int field1; descriptor: I flags: ACC_PRIVATE public com.firelord.zsample.lang.jvm.frontcompiler.Demo2(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: iconst_1 6: putfield #2 // Field field1:I 9: return LineNumberTable: line 3: 0 line 4: 4 LocalVariableTable: Start Length Slot Name Signature 0 10 0 this Lcom/firelord/zsample/lang/jvm/frontcompiler/Demo2; public void hello(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=1 0: iconst_1 1: istore_1 2: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 5: ldc #4 // String hello world 7: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 10: return LineNumberTable: line 7: 0 line 8: 2 line 9: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lcom/firelord/zsample/lang/jvm/frontcompiler/Demo2; 2 9 1 i I }SourceFile: "Demo2.java"3.2.1.Class文件基础信息
Class文件的基础信息包括:
class文件的路径class文件的修改时间、class文件的大小class文件的MD5值java文件的名称jdk的大版本/小版本号3.3.2.常量池
常量池的细节知识有很多,但是有3个关键点:
访问权限、字符串等等,都是JVM所认为的"常量"常量池中存储了多种类型的常量常量之间以类似"指针"的形式来表达源代码
例如:class Demo2,那么常量池有就会有一个UTF-8类型的常量表示"Demo2",还会有一个类的符号引用指向"Demo2"这个UTF-8的常量。
3.3.3.访问标识、类索引
在常量池的基础上,JVM首先要表达源文件中的类,类的关键要素包括:
类名:javap的输出结果中有多处呈现了类名是Demo2。类的访问权限:本例中,javap的输出就是表示Demo2类是public的,并且继承于Object类3.3.4.字段表
进一步,字节码要表达:
Demo2类中有几个字段:javap的输出告诉我们,Demo2只有1个字段field1field1字段的数据类型:从输出可以看到,field1是int类型field1字段的访问权限:从输出可以看出,field1是private3.3.5.方法表
更进一步,字节码要表达:
Demo2类中有几个方法:本例中,有一个默认的构造函数,还有一个hello方法方法的原型:从输出看,hello方法的访问权限是public,返回值是void,没有输入参数方法的具体实现:从输出看,hello方法被转换为了73~88行的JVM指令序列、行号表、局部变量表。4.总结
本文解读了javap的使用以及javap的输出结果,具体如下:
理解字节码以及JVM价值javap的学习方法javap命令行常用optionjavap命令行的options解读字节码的主体结构通过一个示例代码,演练了javap输出结果中各个section的含义5.参考资料
《深入理解Java虚拟机:JVM高级特性与最佳实践》
标签: #javacontentpane