Java字节码创建对象指令

news2024/12/26 23:05:21

接上节。

示例代码:

package com.lkl.jvmDemo;

public class HelloByteCode {
    public static void main(String[] args) {
        HelloByteCode obj = new HelloByteCode();
    }
}

查看字节码清单javap -c -verbose HelloByteCode

Classfile /XXX/com/lkl/jvmDemo/HelloByteCode.class
  Last modified 2023-10-29; size 304 bytes
  MD5 checksum 565e4ca34e83f69df37c1f35c971375f
  Compiled from "HelloByteCode.java"
public class com.lkl.jvmDemo.HelloByteCode
  minor version: 0
  major version: 65
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
   #2 = Class              #4             // java/lang/Object
   #3 = NameAndType        #5:#6          // "<init>":()V
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Class              #8             // com/lkl/jvmDemo/HelloByteCode
   #8 = Utf8               com/lkl/jvmDemo/HelloByteCode
   #9 = Methodref          #7.#3          // com/lkl/jvmDemo/HelloByteCode."<init>":()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               main
  #13 = Utf8               ([Ljava/lang/String;)V
  #14 = Utf8               SourceFile
  #15 = Utf8               HelloByteCode.java
{
  public com.lkl.jvmDemo.HelloByteCode();
    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 3: 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: new           #7                  // class com/lkl/jvmDemo/HelloByteCode
         3: dup
         4: invokespecial #9                  // Method "<init>":()V
         7: astore_1
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 8
}

方法体中的字节码解读

    	 0: new           #7                  // class com/lkl/jvmDemo/HelloByteCode
         3: dup
         4: invokespecial #9                  // Method "<init>":()V
         7: astore_1
         8: return

main方法体中那些字节码指令前面的数字是什么意思,说是序号吧但又不太像,因为他们之间的间隔不相等。

间隔不相等的原因是, 有一部分操作码会附带有操作数, 也会占用字节码数组中的空间

new 就会占用三个槽位: 一个用于存放操作码指令自身,两个用于存放操作数。因此,下一条指令 dup 的索引从 3 开始。

这个方法体变成可视化数组,那么看起来应该是这样的:

image-20231029160412128

每个操作码/指令都有对应的十六进制(HEX)表示形式, 如果换成十六进制来表示,则方法体可表示为HEX字符串。例如上面的方法体百世成十六进制如下所示:

image-20231029160439918

上述02改为07(对应字节码中#7),支持十六进制的编辑器中打开 class 文件,可以在其中找到对应的字符串:

image-20231029160747543

对象初始化指令:new 指令, init 以及 clinit 简介

new是 Java 编程语言中的一个关键字, 但其实在字节码中,也有一个指令叫做 new。 创建类的实例时, 编译器会生成类似下面这样的操作码:

    	 0: new           #7                  // class com/lkl/jvmDemo/HelloByteCode
         3: dup
         4: invokespecial #9                  // Method "<init>":()V

同时看到 new, dupinvokespecial 指令在一起时,那么一定是在创建类的实例对象!

为什么是三条指令而不是一条呢?这是因为:

  • new 指令只是创建对象,但没有调用构造函数
  • invokespecial 指令用来调用某些特殊方法的,当然这里调用的是构造函数。
  • dup 指令用于复制栈顶的值。

由于构造函数调用不会返回值,所以如果没有 dup 指令, 在对象上调用方法并初始化之后,操作数栈就会是空的,在初始化之后就会出问题, 接下来的代码就无法对其进行处理。

这就是为什么要事先复制引用的原因,为的是在构造函数返回之后,可以将对象实例赋值给局部变量或某个字段。因此,接下来的那条指令一般是以下几种:

  • astore {N} or astore_{N} – 赋值给局部变量,其中 {N} 是局部变量表中的位置。
  • putfield – 将值赋给实例字段
  • putstatic – 将值赋给静态字段

调用构造函数的时候,其实还会执行另一个类似的方法 <init> ,甚至在执行构造函数之前就执行了。

还有一个可能执行的方法是该类的静态初始化方法 <clinit>, 但 <clinit> 并不能被直接调用,而是由这些指令触发的: new, getstatic, putstatic or invokestatic

也就是说,如果创建某个类的新实例, 访问静态字段或者调用静态方法,就会触发该类的静态初始化方法【如果尚未初始化】。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1147638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【电路笔记】-交流电阻和阻抗

交流电阻和阻抗 文章目录 交流电阻和阻抗1、概述&#xff1a;电阻率2、交流状态与直流状态近似性3、交流状态与直流状态的差异性3.1 趋肤效应(The Skin Effect)3.2 靠近效应&#xff08;The Proximity Effect&#xff09; 4、总结 电阻是一种特性&#xff0c;用于表征当电压差施…

2023最流行的自动化测试工具有哪些?

一&#xff1a;前言 随着测试工程师技能和工资待遇的提升&#xff0c;甚至有一部分的开发人员开始转入测试岗位&#xff0c;跨入自动化领域的测试攻城狮越来越多。在自动化测试领域&#xff0c;自动化工具肯定占据了核心的位置。 本文总结了常用的测试自动化工具和框架&#x…

【机器学习可解释性】5.SHAP值的高级使用

机器学习可解释性 1.模型洞察的价值2.特征重要性排列3.部分依赖图4.SHAP 值5.SHAP值的高级使用 正文 汇总SHAP值以获得更详细的模型解释 总体回顾 我们从学习排列重要性和部分依赖图开始&#xff0c;以显示学习后的模型的内容。 然后我们学习了SHAP值来分解单个预测的组成部…

汇编语言-div指令溢出问题

汇编语言-div指令溢出问题 8086CPU中被除数保存在ax(16位)或ax和dx&#xff08;32位&#xff09;中&#xff0c;如果被除数为16位&#xff0c;进行除法运算时al保存商&#xff0c;ah保存余数。如果被除数为32位时&#xff0c;进行除法运算时&#xff0c;ax保存商&#xff0c;d…

从最简单基本开始 or 把问题复杂化还自诩为“设计了一个可扩展的系统”?

文章目录 Intro程序员“把问题复杂化”的职业病如何抉择 Intro 刚才看了一段关于在苹果系统中使用numbers表格软件制作记账本的视频教程&#xff1a;当 Excel 交给苹果来设计会变成…&#xff1f;#Numbers 新手教学&#xff0c;以下为最终界面效果&#xff1a; 有些触动&…

网络原理续

传输层的协议也并非就只有UDP和TCP 就拿王者荣耀这个游戏来说 是否需要可靠性是否需要高效率 那是使用TCP还是UDP呢? 当然是都不用, 除了这两个协议外, 有的传输层协议就是为游戏场景量身打造的. 比如说以KCP为代表的一系列协议. 网络层 地址管理路由选择 网络层的代表:…

【FreeRTOS】

FreeRTOS 一、FreeRTOS任务创建和删除1.1 动态方式1.2 静态方式 二、任务挂起和恢复三、中断管理四、临界区保护及调度器的挂起和恢复五、列表项的插入和删除六、时间片调度七、任务状态查询API函数介绍7.1 任务状态查询API7.2 任务运行时间统计API 八、时间管理九、队列十、信…

SpringBoot小项目——简单的小区物业后台管理系统 认证鉴权 用户-角色模型 AOP切面日志 全局异常【源码】

目录 引出一、应用到的技术栈Spring、Spring MVC、Spring Boot基础SpringBoot进阶、SpringMVC原理、AOP切面MyBatis 数据库相关JavaWeb基础&#xff1a;Session等前端Vue、JavaScript、Bootstrap 二、后台管理系统的功能登录功能1.用户名密码登录2.验证码的登录 报修业务的处理…

【多线程面试题十】、说一说notify()、notifyAll()的区别

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说notify()、notify…

C++哈希表:一种快速查找和插入的方法

文章目录 1、前言2、unordered系列关联式容器2.1、 unordered_map2.1.1、unordered_map的文档介绍2.1.2、unordered_map的接口说明 2.2、 unordered_set 3. 底层结构3.1 哈希概念3.2 哈希冲突2.3 哈希函数2.4 哈希冲突解决2.4.1 闭散列2.4.2 开散列 4. 模拟实现4.1 哈希表的改造…

论文速递 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统

注1:本文系“最新论文速览”系列之一,致力于简洁清晰地介绍、解读最新的顶会/顶刊论文 TMC 2023 | RoSeFi: 一种利用商用WiFi设备进行稳健的久坐行为监测系统 原文链接:https://ieeexplore.ieee.org/abstract/document/10269067 本文提出了一种稳健的久坐行为监测系统RoSeFi。…

ITSource 分享 第5期【校园信息墙系统】

项目介绍 本期给大家介绍一个 校园信息墙 系统&#xff0c;可以发布信息&#xff0c;表白墙&#xff0c;分享墙&#xff0c;校园二手买卖&#xff0c;咨询分享等墙信息。整个项目还是比较系统的&#xff0c;分为服务端&#xff0c;管理后台&#xff0c;用户Web端&#xff0c;小…

SHCTF 山河CTF Reverse方向[Week1]全WP 详解

文章目录 [WEEK1]ez_asm[WEEK1]easy_re[WEEK1]seed[WEEK1]signin[WEEK1]easy_math[WEEK1]ez_apk [WEEK1]ez_asm 从上往下读&#xff0c;第一处是xor 1Eh&#xff0c;第二处是sub 0Ah&#xff1b;逆向一下先加0A后异或1E 写个EXP data "nhuo[M7mc7uhc$7midgbTf7$7%#ubf7 …

Go命令行参数操作:os.Args、flag包

Go命令行参数操作&#xff1a;os.Args、flag包 最近在写项目时&#xff0c;需要用到命令行传入的参数&#xff0c;正好借此机会整理一下。 1 os.Args&#xff1a;程序运行时&#xff0c;携带的参数&#xff08;包含exe本身&#xff09; package mainimport ("fmt"&q…

ZYNQ连载02-开发环境

ZYNQ连载02-开发环境 1. 官方文档 ZYNQ开发使用的软件为Vivado/Vitis/PetaLinux,软件体积比较大&#xff0c;硬盘保留100G以上的空间&#xff0c;赛灵思提供详细的文档&#xff0c;链接如下&#xff1a; ZYNQ文档 2. Vivido和Vitis安装 赛灵思统一安装程序 3. PetaLinux安装…

OV-VG: A Benchmark for Open-Vocabulary Visual Grounding

OV-VG: A Benchmark for Open-Vocabulary Visual Grounding 一、Abstract 写在前面 又是一周周末&#xff0c;光调代码去了&#xff0c;都没时间看论文了&#xff0c;汗。   这是一篇关于开放词汇定位的文章&#xff0c;也是近两年的新坑&#xff0c;但是资源也是需要不少。 …

波士顿房价预测

目录 1.初始化库并导入数据 2.查看是否有缺失值&#xff0c;查看各个变量的相关性 3.探究各变量之间的相关关系 4.初始化并训练线性模型 5.可视化预测情况 6.模型优化 idea1&#xff1a;减少决策变量 idea2&#xff1a;数据归一化 idea3&#xff1a;尝试其他模型 XGB…

Vue $nextTick 模板解析后在执行的函数

this.$nextTick(()>{ 模板解析后在执行的函数 })

智慧矿山AI算法助力护帮板支护监测,提升安全与效率

在智慧矿山AI算法系列中&#xff0c;护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分&#xff0c;在矿山生产中起到了关键的作用。那么&#xff0c;护帮板在哪种状态下是正常打开的呢&#xff1f;本文将对此进行介绍。 护帮板的…

搭建MyBatis

文章目录 1.创建Maven 工程创建MyBatis的核心配置文件创建mapper接口创建MyBatis的映射文件通过junit测试功能加入log4j日志功能核心配置文件详解1.这里实现了jdbc.properties jdbc.properties文件 默认的类型别名MyBatis的增删改查 1.创建Maven 工程 打包方式&#xff1a;jar…