我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java字节码的知识点有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java字节码的知识点有哪些

这篇文章主要为大家展示了“Java字节码的知识点有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java字节码的知识点有哪些”这篇文章吧。

编译“1+1”代码

首先我们需要写个简单的小程序,1+1的程序,学习就要从最简单的1+1开始,代码如下:

package top.luozhou.test;public class TestJava {         public static void main(String[] args) {         int a=1+1;        System.out.println(a);    }}

写好java类文件后,首先执行命令javac TestJava.java 编译类文件,生成TestJava.class。 然后执行反编译命令javap -verbose TestJava,字节码结果显示如下:

  Compiled from "TestJava.java"public class top.luozhou.test.TestJava  minor version: 0  major version: 56  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Methodref          #5.#14         // java/lang/Object."<init>":()V   #2 = Fieldref           #15.#16        // java/lang/System.out:Ljava/io/PrintStream;   #3 = Methodref          #17.#18        // java/io/PrintStream.println:(I)V   #4 = Class              #19            // top/luozhou/test/TestJava   #5 = Class              #20            // java/lang/Object   #6 = Utf8               <init>   #7 = Utf8               ()V   #8 = Utf8               Code   #9 = Utf8               LineNumberTable  #10 = Utf8               main  #11 = Utf8               ([Ljava/lang/String;)V  #12 = Utf8               SourceFile  #13 = Utf8               TestJava.java  #14 = NameAndType        #6:#7          // "<init>":()V  #15 = Class              #21            // java/lang/System  #16 = NameAndType        #22:#23        // out:Ljava/io/PrintStream;  #17 = Class              #24            // java/io/PrintStream  #18 = NameAndType        #25:#26        // println:(I)V  #19 = Utf8               top/luozhou/test/TestJava  #20 = Utf8               java/lang/Object  #21 = Utf8               java/lang/System  #22 = Utf8               out  #23 = Utf8               Ljava/io/PrintStream;  #24 = Utf8               java/io/PrintStream  #25 = Utf8               println  #26 = Utf8               (I)V{  public top.luozhou.test.TestJava();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0         1: invokespecial #1                  // Method java/lang/Object."<init>":()V         4: return      LineNumberTable:        line 8: 0  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=2, args_size=1         0: iconst_2         1: istore_1         2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;         5: iload_1         6: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V         9: return      LineNumberTable:        line 10: 0        line 11: 2        line 12: 9}

解析字节码

基础信息

上述结果删除了部分不影响解析的冗余信息,接下来我们便来解析字节码的结果。

 minor version: 0 次版本号,为0表示未使用 major version: 56 主版本号,56表示jdk12,表示只能运行在jdk12版本以及之后的虚拟机中
flags: ACC_PUBLIC, ACC_SUPER

ACC_PUBLIC:这就是一个是否是public类型的访问标志。

ACC_SUPER: 这个falg是为了解决通过 invokespecial 指令调用 super 方法的问题。可以将它理解成 Java 1.0.2 的一个缺陷补丁,只有通过这样它才能正确找到 super 类方法。从 Java 1.0.2 开始,编译器始终会在字节码中生成 ACC_SUPER 访问标识。感兴趣的同学可以点击这里来了解更多。

常量池

接下来,我们将要分析常量池,你也可以对照上面整体的字节码来理解。

#1 = Methodref          #5.#14         // java/lang/Object."<init>":()V

这是一个方法引用,这里的#5表示索引值,然后我们可以发现索引值为5的字节码如下

#5 = Class              #20            // java/lang/Object

它表示这是一个Object类,同理#14指向的是一个"<init>":()V表示引用的是初始化方法。

#2 = Fieldref           #15.#16        // java/lang/System.out:Ljava/io/PrintStream;

上面这段表示是一个字段引用,同样引用了#15和#16,实际上引用的就是java/lang/System类中的PrintStream对象。其他的常量池分析思路是一样的,鉴于篇幅我就不一一说明了,只列下其中的几个关键类型和信息。

NameAndType:这个表示是名称和类型的常量表,可以指向方法名称或者字段的索引,在上面的字节码中都是表示的实际的方法。

Utf8:我们经常使用的是字符编码,但是这个不是只有字符编码的意思,它表示一种字符编码是Utf8的字符串。它是虚拟机中最常用的表结构,你可以理解为它可以描述方法,字段,类等信息。 比如:

#4 = Class              #19 #19 = Utf8               top/luozhou/test/TestJava

这里表示#4这个索引下是一个类,然后指向的类是#19,#19是一个Utf8表,最终存放的是top/luozhou/test/TestJava,那么这样一连接起来就可以知道#4位置引用的类是top/luozhou/test/TestJava了。

构造方法信息

接下来,我们分析下构造方法的字节码,我们知道,一个类初始化的时候最先执行它的构造方法,如果你没有写构造方法,系统会默认给你添加一个无参的构造方法。

public top.luozhou.test.TestJava();        descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0                  1: invokespecial #1                  // Method java/lang/Object."<init>":()V         4: return      LineNumberTable:        line 8: 0

descriptor: ()V :表示这是一个没有返回值的方法。

flags: ACC_PUBLIC:是公共方法。

stack=1, locals=1, args_size=1 :表示栈中的数量为1,局部变量表中的变量为1,调用参数也为1。

这里为什么都是1呢?这不是默认的构造方法吗?哪来的参数?其实Java语言有一个潜规则:在任何实例方法里面都可以通过this来访问到此方法所属的对象。而这种机制的实现就是通过Java编译器在编译的时候作为入参传入到方法中了,熟悉python语言的同学肯定会知道,在python中定义一个方法总会传入一个self的参数,这也是传入此实例的引用到方法内部,Java只是把这种机制后推到编译阶段完成而已。所以,这里的1都是指this这个参数而已。

         0: aload_0         1: invokespecial #1                  // Method java/lang/Object."<init>":()V         4: return    LineNumberTable:        line 8: 0

经过上面这个分析对于这个构造方法表达的意思也就很清晰了。

aload_0:表示把局部变量表中的第一个变量加载到栈中,也就是this。

invokespecial:直接调用初始化方法。

return:调用完毕方法结束。

LineNumberTable:这是一个行数的表,用来记录字节码的偏移量和代码行数的映射关系。line 8: 0表示,源码中第8行对应的就是偏移量0的字节码,因为是默认的构造方法,所以这里并无法直观体现出来。

另外这里会执行Object的构造方法是因为,Object是所有类的父类,子类的构造要先构造父类的构造方法。

main方法信息

public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=2, args_size=1         0: iconst_2         1: istore_1         2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;         5: iload_1         6: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V         9: return      LineNumberTable:        line 10: 0        line 11: 2        line 12: 9

有了之前构造方法的分析,我们接下来分析main方法也会熟悉很多,重复的我就略过了,这里重点分析code部分。

stack=2, locals=2, args_size=1:这里的栈和局部变量表为2,参数还是为1。这是为什么呢?因为main方法中声明了一个变量a,所以局部变量表要加一个,栈也是,所以他们是2。那为什么args_size还是1呢?你不是说默认会把this传入的吗?应该是2啊。注意:之前说的是在任何实例方法中,而这个main方法是一个静态方法,静态方法直接可以通过类+方法名访问,并不需要实例对象,所以这里就没必要传入了。

0: iconst_2:将int类型2推送到栈顶。

istore_1:将栈顶int类型数值存入第二个本地变量。

getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;:获取PrintStream类。

iload_1: 把第二个int型本地变量推送到栈顶。

invokevirtual #3 // Method java/io/PrintStream.println:(I)V:调用println方法。

return:调用完毕结束方法。

这里的LineNumberTable是有源码的,我们可以对照下我前面描述是否正确:

Java字节码的知识点有哪些

line 10: 0: 第10行表示 0: iconst_2字节码,这里我们发现编译器直接给我们计算好了把2推送到栈顶了。

line 11: 2:第11行源码对应的是 2: getstatic 获取输出的静态类PrintStream。

line 12: 9:12行源码对应的是return,表示方法结束。

这里我也画了一个动态图片来演示main方法执行的过程,希望能够帮助你理解:

Java字节码的知识点有哪些

以上是“Java字节码的知识点有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java字节码的知识点有哪些

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java字节码的知识点有哪些

这篇文章主要为大家展示了“Java字节码的知识点有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java字节码的知识点有哪些”这篇文章吧。编译“1+1”代码首先我们需要写个简单的小程序,1+
2023-06-02

Java字节码增强技术知识点有哪些

这篇文章主要介绍了Java字节码增强技术知识点有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。ASMASM是一个Java字节码操控框架,它能被用来动态生成类或者增强既有类
2023-06-20

Python字符编码知识点有哪些

本篇内容主要讲解“Python字符编码知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python字符编码知识点有哪些”吧!1.字符编码【所谓unicode】unicode是一种类似于
2023-06-02

Java NIO的知识点有哪些

今天小编给大家分享一下Java NIO的知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。No-Block 和Blo
2023-06-17

java的Classpath知识点有哪些

本篇内容主要讲解“java的Classpath知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java的Classpath知识点有哪些”吧!java的优点就是他是一个自动支持网络功能的
2023-06-03

Java栈的知识点有哪些

这篇文章主要介绍了Java栈的知识点有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java栈的知识点有哪些文章都会有所收获,下面我们一起来看看吧。1.栈的概念栈(stack)又名堆栈,作为一种数据结构,是
2023-06-29

Java的Queue知识点有哪些

本篇内容主要讲解“Java的Queue知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java的Queue知识点有哪些”吧!Java提供了Quere,相当好用,在1.5版本中又有增强。
2023-06-03

java URL知识点有哪些

本篇内容主要讲解“java URL知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java URL知识点有哪些”吧!01、什么是 URL为了搞清楚什么是 URL,需要引入另外两个概念
2023-06-19

Java Unsafe知识点有哪些

本篇内容介绍了“Java Unsafe知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!sun.misc.Unsafe作用:可以用来
2023-06-25

Python编码的知识点有哪些

这篇文章主要介绍“Python编码的知识点有哪些”,在日常操作中,相信很多人在Python编码的知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python编码的知识点有哪些”的疑惑有所帮助!接下来
2023-06-16

Java继承的知识点有哪些

今天小编给大家分享一下Java继承的知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。继承继承的介绍继承是java面
2023-06-29

Java之JVM的知识点有哪些

今天小编给大家分享一下Java之JVM的知识点有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一.JVM内存区域划分JV
2023-07-02

JAVA技术的知识点有哪些

这篇文章主要讲解了“JAVA技术的知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JAVA技术的知识点有哪些”吧!  一、Java的跨平台性,即一次编译到处运行   简单地说Jav
2023-06-03

Java对象的知识点有哪些

这篇文章主要讲解了“Java对象的知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java对象的知识点有哪些”吧!1、问题的复杂性直接取决于抽象的类型和质量,同一个问题,如果抽象的
2023-06-03

java的重要知识点有哪些

本篇内容介绍了“java的重要知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Spring Cloud Config配置管理工具包
2023-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录