博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
轻松读懂字节码文件
阅读量:4181 次
发布时间:2019-05-26

本文共 9490 字,大约阅读时间需要 31 分钟。

  • invokeinterface: 调用接口方法

  • invokespecial: 调用初始化方法、私有方法、或父类中定义的方法

  • invokestatic: 调用静态方法

  • invokevirtual: 调用实例方法

package com.xiaobu.test.StringDemo;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/4/30 16:04 * @description V1.0 走StringBuilder */public class StringDemo3 {
public static void main(String[] args) {
test1(); } //结果为false private static void test1() {
String str = "123"; String a = "123"; String str2 = a + ""; System.out.println(str==str2); }}

使用idea插件反编译字节码文件

Classfile /E:/Practise/SpringBoot/demo/target/classes/com/xiaobu/test/StringDemo/StringDemo3.class  Last modified 2019-10-22; size 1020 bytes  MD5 checksum fd43b6950ccbd87c2bdd41457f4e50b1  Compiled from "StringDemo3.java"public class com.xiaobu.test.StringDemo.StringDemo3  minor version: 0  major version: 52   //表明是JDK1.8  flags: ACC_PUBLIC, ACC_SUPER  //类的访问标志Constant pool:        //常量池   #1 = Methodref          #12.#35        // java/lang/Object."
":()V #+数字表示第几个常量 这个指向父类的构造方法 #2 = Methodref #11.#36 // com/xiaobu/test/StringDemo/StringDemo3.test1:()V 指向test1()方法 返回值void #3 = String #37 // 123 #4 = Class #38 // java/lang/StringBuilder #5 = Methodref #4.#35 // java/lang/StringBuilder."
":()V #6 = Methodref #4.#39 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #7 = String #40 // #8 = Methodref #4.#41 // java/lang/StringBuilder.toString:()Ljava/lang/String; #9 = Fieldref #42.#43 // java/lang/System.out:Ljava/io/PrintStream; #10 = Methodref #44.#45 // java/io/PrintStream.println:(Z)V #11 = Class #46 // com/xiaobu/test/StringDemo/StringDemo3 #12 = Class #47 // java/lang/Object #13 = Utf8
#14 = Utf8 ()V #15 = Utf8 Code #16 = Utf8 LineNumberTable #17 = Utf8 LocalVariableTable #18 = Utf8 this #19 = Utf8 Lcom/xiaobu/test/StringDemo/StringDemo3; #20 = Utf8 main #21 = Utf8 ([Ljava/lang/String;)V #22 = Utf8 args #23 = Utf8 [Ljava/lang/String; #24 = Utf8 MethodParameters #25 = Utf8 test1 #26 = Utf8 str #27 = Utf8 Ljava/lang/String; #28 = Utf8 a #29 = Utf8 str2 #30 = Utf8 StackMapTable #31 = Class #48 // java/lang/String #32 = Class #49 // java/io/PrintStream #33 = Utf8 SourceFile #34 = Utf8 StringDemo3.java #35 = NameAndType #13:#14 // "
":()V #36 = NameAndType #25:#14 // test1:()V #37 = Utf8 123 #38 = Utf8 java/lang/StringBuilder #39 = NameAndType #50:#51 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #40 = Utf8 #41 = NameAndType #52:#53 // toString:()Ljava/lang/String; #42 = Class #54 // java/lang/System #43 = NameAndType #55:#56 // out:Ljava/io/PrintStream; #44 = Class #49 // java/io/PrintStream #45 = NameAndType #57:#58 // println:(Z)V #46 = Utf8 com/xiaobu/test/StringDemo/StringDemo3 #47 = Utf8 java/lang/Object #48 = Utf8 java/lang/String #49 = Utf8 java/io/PrintStream #50 = Utf8 append #51 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #52 = Utf8 toString #53 = Utf8 ()Ljava/lang/String; #54 = Utf8 java/lang/System #55 = Utf8 out #56 = Utf8 Ljava/io/PrintStream; #57 = Utf8 println #58 = Utf8 (Z)V{
public com.xiaobu.test.StringDemo.StringDemo3(); //默认构造方法 descriptor: ()V flags: ACC_PUBLIC Code: //code表示代码 stack:最大操作数栈 locals:局部变量锁存储的空间:4个字节大小 stack=1, locals=1, args_size=1 // args_size方法参数个数 0: aload_0 //将第一个引用类型本地变量推送至栈顶 1: invokespecial #1 // Method java/lang/Object."
":()V 4: return //方法返回 LineNumberTable: line 9: 0 //第九行源码对应 字节码行号0: aload_0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/xiaobu/test/StringDemo/StringDemo3; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: invokestatic #2 // Method test1:()V 3: return //方法返回 LineNumberTable: line 11: 0 //第十一行源码对应 字节码行号0: invokestatic #2 line 12: 3 //第十二行源码对应 字节码行号3: return LocalVariableTable: Start Length Slot Name Signature 0 4 0 args [Ljava/lang/String; MethodParameters: Name Flags args}SourceFile: "StringDemo3.java"

可以看出上面代码底层走了StringBuilder,进行字符串拼接,然后调用了StringBuilder的toString方法。

package com.xiaobu.test.StringDemo;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2019/4/30 16:04 * @description V1.0 走String */public class StringDemo4 {
public static void main(String[] args) {
test1(); } //结果为true private static void test1() {
String str = "11"; String a = "11"; String str2 = "11" + ""; System.out.println(str==str2); }}

反编译字节码文件

Classfile /E:/Practise/SpringBoot/demo/target/classes/com/xiaobu/test/StringDemo/StringDemo4.class  Last modified 2019-10-22; size 851 bytes  MD5 checksum 045bcada94c8d6c922754d92f6242259  Compiled from "StringDemo4.java"public class com.xiaobu.test.StringDemo.StringDemo4  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #7.#30         // java/lang/Object."
":()V #2 = Methodref #6.#31 // com/xiaobu/test/StringDemo/StringDemo4.test1:()V #3 = String #32 // 11 #4 = Fieldref #33.#34 // java/lang/System.out:Ljava/io/PrintStream; #5 = Methodref #35.#36 // java/io/PrintStream.println:(Z)V #6 = Class #37 // com/xiaobu/test/StringDemo/StringDemo4 #7 = Class #38 // java/lang/Object #8 = Utf8
#9 = Utf8 ()V #10 = Utf8 Code #11 = Utf8 LineNumberTable #12 = Utf8 LocalVariableTable #13 = Utf8 this #14 = Utf8 Lcom/xiaobu/test/StringDemo/StringDemo4; #15 = Utf8 main #16 = Utf8 ([Ljava/lang/String;)V #17 = Utf8 args #18 = Utf8 [Ljava/lang/String; #19 = Utf8 MethodParameters #20 = Utf8 test1 #21 = Utf8 str #22 = Utf8 Ljava/lang/String; #23 = Utf8 a #24 = Utf8 str2 #25 = Utf8 StackMapTable #26 = Class #39 // java/lang/String #27 = Class #40 // java/io/PrintStream #28 = Utf8 SourceFile #29 = Utf8 StringDemo4.java #30 = NameAndType #8:#9 // "
":()V #31 = NameAndType #20:#9 // test1:()V #32 = Utf8 11 #33 = Class #41 // java/lang/System #34 = NameAndType #42:#43 // out:Ljava/io/PrintStream; #35 = Class #40 // java/io/PrintStream #36 = NameAndType #44:#45 // println:(Z)V #37 = Utf8 com/xiaobu/test/StringDemo/StringDemo4 #38 = Utf8 java/lang/Object #39 = Utf8 java/lang/String #40 = Utf8 java/io/PrintStream #41 = Utf8 java/lang/System #42 = Utf8 out #43 = Utf8 Ljava/io/PrintStream; #44 = Utf8 println #45 = Utf8 (Z)V{
public com.xiaobu.test.StringDemo.StringDemo4(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."
":()V 4: return LineNumberTable: line 9: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/xiaobu/test/StringDemo/StringDemo4; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: invokestatic #2 // Method test1:()V 3: return LineNumberTable: line 11: 0 line 12: 3 LocalVariableTable: Start Length Slot Name Signature 0 4 0 args [Ljava/lang/String; MethodParameters: Name Flags args}SourceFile: "StringDemo4.java"

上面直接走的字符串拼接。

参考:

转载地址:http://zwgai.baihongyu.com/

你可能感兴趣的文章
CSDN-markdown编辑器
查看>>
拷贝整个目录到另一台服务器并排除log目录
查看>>
拜托,面试别再问我跳表了!
查看>>
android ArrayList<String> 转 String[]
查看>>
RecyclerView baseadapter
查看>>
Android中应用程序如何获得系统签名权限
查看>>
Recycler表格(excelPanel)
查看>>
android一行代码实现沉浸式布局效果
查看>>
json, recyclerView问题
查看>>
cmake处理多源文件目录的方法
查看>>
Service Intent must be explicit
查看>>
android studio SDK开发
查看>>
studio 统计代码的行数
查看>>
字符数组和16进制互换
查看>>
PHP项目中出现致命错误: Class 'Redis' not found
查看>>
There is no tracking information for the current branch.
查看>>
fatal: refusing to merge unrelated histories
查看>>
Git命令还原未提交的变更
查看>>
Linux系统中环境变量的配置
查看>>
Linux系统中配置脚本程序开机启动
查看>>