已知有两个类:

public class Father extends GrandFather {

public String name = "father";

public void show() {

System.out.println("father");

}

public Father me() {

return this;

}

}

public class Son extends Father {

public void show() {

System.out.println("son");

}

}

把下面字节码转为源码。

// class version 54.0 (54)

// access flags 0x21

public class com/demo/Test {

// compiled from: Test.java

// 类的初始化过程都在这。先忽略 init

// access flags 0x1

public ()V

L0

LINENUMBER 3 L0

ALOAD 0

INVOKESPECIAL java/lang/Object. ()V

RETURN

L1

LOCALVARIABLE this Lcom/demo/Test; L0 L1 0

MAXSTACK = 1

MAXLOCALS = 1

// 重点是将下面的转为源码就可以

// access flags 0x9

// 定义了 static void main(String[] args) [出现几次就是几维数组。那么形参名为什么是args?看最下面的 L8的局部变量表可以找出是args

public static main([Ljava/lang/String;)V

L0 // Father son = new Son();

LINENUMBER 5 L0 // 文件的第五行

NEW com/demo/Son // new Son()

DUP // 复制栈顶操作数压入栈

INVOKESPECIAL com/demo/Son. ()V 执行son的 初始化

ASTORE 1 // 把对象存在局部变量表1的位置,也就是L8 中的 Father son

L1

LINENUMBER 7 L1 // 第七行

GETSTATIC java/lang/System.out : Ljava/io/PrintStream; // 调用 System.out 常量

ALOAD 1 // 把局部变量表位置为1的变量压入栈。也就是将Son变量作为下面println的操作数(参数)

INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V // 最终结果: System.out.println(son);

L2

LINENUMBER 8 L2

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;

ALOAD 1

INVOKEVIRTUAL com/demo/Father.me ()Lcom/demo/Father;

// 难点在于:println的操作数是哪一个? son 还是 son.me()。因为这里没有产生其他中间变量。因此猜测是链式调用

INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V // 结果 System.out.println(son.me())

L3

LINENUMBER 9 L3

ALOAD 1

INVOKEVIRTUAL com/demo/Father.show ()V // 结果 son.show()

L4

LINENUMBER 10 L4

ALOAD 1

INVOKEVIRTUAL com/demo/Father.me ()Lcom/demo/Father;

INVOKEVIRTUAL com/demo/Father.show ()V // 结果:

L5

LINENUMBER 11 L5

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;

ALOAD 1

GETFIELD com/demo/Father.name : Ljava/lang/String;

INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V // 结果: System.out.println(son.name)

L6

LINENUMBER 12 L6

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;

ALOAD 1

INVOKEVIRTUAL com/demo/Father.me ()Lcom/demo/Father;

GETFIELD com/demo/Father.name : Ljava/lang/String;

// 难点在于 System.out.println(son.me().name) 还是 System.out.println(son.name)因为两个能匹配下面的方法签名。

// 因为只有一次 ALOAD,这里肯定是前者。后者需要两次ALOAD:son.me(); System.out.println(son.name); 也就是son出现两次

INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V // 结果: System.out.println(son.me().name)

L7

LINENUMBER 13 L7

RETURN // 方法结束

L8

LOCALVARIABLE args [Ljava/lang/String; L0 L8 0 // 猜测 L0 L8应该是作用域范围,后面的0则是处于变量表的位置

LOCALVARIABLE son Lcom/demo/Father; L1 L8 1

MAXSTACK = 2 // 这个栈是操作数栈还是虚拟机栈?

MAXLOCALS = 2 // 最多存在多少个局部变量

}

最后结果:

public class Test {

public static void main(String[] args) {

Father son = new Son();

System.out.println(son);

System.out.println(son.me());

son.show();

son.me().show();

System.out.println(son.name);

System.out.println(son.me().name);

}

}

还有个问题是,上面没有对应行号。

java自带的字节码技术_读懂字节码-还原JAVA源码相关推荐

  1. Linux 信号量 源码,一文读懂go中semaphore(信号量)源码

    运行时信号量机制 semaphore 前言 最近在看源码,发现好多地方用到了这个semaphore. 本文是在go version go1.13.15 darwin/amd64上进行的 作用是什么 下 ...

  2. thinkphp多城市房产系统源码程序_亲测Thinkphp开源房产程序源码/多城市版房产系统 带手机版+独家教程...

    「亲测」Thinkphp开源房产程序源码/多城市版房产系统 带手机版+独家教程+去授权+独家修复 本套tp房产源码包含:管理总后台.代理后台.用户中心.前台.PC端.手机版等,pc和手机端的数据同步, ...

  3. git 拉取 未能顺利结束 (退出码 1)_小白的 asyncio :原理、源码 到实现(1)

    去年的这个时候吧,我开始找工作,招聘启事上说,需要了解 asyncio. 我回去翻了翻书,orz····· 今年,在一次内部技术分享会上,我要分享的内容涉及到一些 python 协程,我又去看 asy ...

  4. Android 框架学习4:一次读懂热门图片框架 Picasso 源码及流程

    Android 框架学习1:EventBus 3.0 的特点与如何使用 Android 框架学习2:源码分析 EventBus 3.0 如何实现事件总线 Android 框架学习3:我从 EventB ...

  5. 基于java技术的装潢公司网站开发计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署

    基于java技术的装潢公司网站开发计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java技术的装潢公司网站开发计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 本源 ...

  6. java毕业设计——基于java+eclipse+sqlserver的银行帐目管理系统设计与实现(毕业论文+程序源码)——银行帐目管理系统

    基于java+eclipse+sqlserver的银行帐目管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+eclipse+sqlserver的银行帐目管理系统设计与实现, ...

  7. java毕业设计——基于java+EVENODD编码的基于纠错码的冗余技术设计与实现(毕业论文+程序源码)——基于纠错码的冗余技术

    基于java+EVENODD编码的基于纠错码的冗余技术设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+EVENODD编码的基于纠错码的冗余技术设计与实现,文章末尾附有本毕业设计的 ...

  8. java数字家谱管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署

    java数字家谱管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 java数字家谱管理系统设计与实现计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 本源码技 ...

  9. java计算机毕业设计数字家谱管理系统设计与实现MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计数字家谱管理系统设计与实现MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计数字家谱管理系统设计与实现MyBatis+系统+LW文档+源码+调试部署 本源码技 ...

最新文章

  1. ansible-playbook相关
  2. python京东抢购脚本_五个月抢京东抢茅台心得
  3. java对象引用传递和值传递的一些总结
  4. Pytorch中的torch.nn.Embedding()
  5. 接口配置锦囊妙计之三----端口自协商
  6. 一文读懂增强现实(AR)技术
  7. python列举字符串的五种常用方法_python中字符串、列表、元组、字典每个常用的5个方法...
  8. 多台路由器连接,实现全网可达
  9. Java实现模拟斗地主洗牌、发牌、看牌并排序
  10. R语言关于心脏病相关问题的预测和分析
  11. linux科学计算器_2个适用于Linux桌面的科学计算器
  12. no applicable items eclipse
  13. 计算机网络回环测试命令,实验二 常用网络测试命令.doc
  14. 【ZOJ 4062】Plants vs. Zombies
  15. 产业分析:快手私域经营
  16. JS与JQ基础练习---侧栏二级菜单操作
  17. 【Blender】快捷键大全(带导图)
  18. 强引用、软引用、弱引用、虚引用介绍
  19. 关于微信小程序富文本编辑器回显数据初始化editor的时候,页面滑动到最底部了
  20. python+vue+elementui大学生网络教学平台

热门文章

  1. CNN vs RNN vs ANN——3 种神经网络分析模型,你 Pick 谁?
  2. 双十一,老板的电话该不该接?
  3. 软件绿色联盟开发者大会惊喜不断,今日还有重磅议程!
  4. ICCV 2019 中国论文数量超美国,商汤57篇论文入选!
  5. ​JavaScript 开发人员的主要基本技能是?
  6. 300 秒搞定第一超算 1 万年的计算量,量子霸权时代已来? | CSDN 博文精选
  7. 虚拟化技术发展编年史
  8. @程序员,欠下的技术债怎么还?
  9. 不了解这些“高级货”,活该面试当炮灰......
  10. JavaScript 凭什么力压 Java、Python 横扫编程语言榜单?