ASM Java字节码操作框架入门学习 输出Hello World

这篇具有很好参考价值的文章主要介绍了ASM Java字节码操作框架入门学习 输出Hello World。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ASM Java字节码操作框架入门学习 输出Hello World

1.类信息

package org.example;

public class Hello {

    public void say(){
        System.out.println("hello world");
    }

}

查看字节码信息

ASM Java字节码操作框架入门学习 输出Hello World,JVM,学习,java,开发语言

 			//动态设置栈大小
        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

       //设置类的基本信息
        classWriter.visit(
                V1_8, //设置JDK版本,
                ACC_PUBLIC, // 设置权限修饰符,
                "Hello", //新类的权限定类名,
                null,//泛型
                "java/lang/Object", // 父类
                null//实现的接口
        );

2.无参构造方法

ASM Java字节码操作框架入门学习 输出Hello World,JVM,学习,java,开发语言

0 aload_0
1 invokespecial #1 <java/lang/Object.<init> : ()V>
4 return

  			MethodVisitor constructor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        constructor.visitVarInsn(Opcodes.ALOAD, 0); //操作局部变量表 局部变量表第一个存放this
        constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        constructor.visitInsn(Opcodes.RETURN); // 调用  return 指令
        constructor.visitMaxs(1, 1);//方法的最大栈大小  方法的最大局部变量数
        constructor.visitEnd(); //方法结束

3.say 方法

ASM Java字节码操作框架入门学习 输出Hello World,JVM,学习,java,开发语言文章来源地址https://www.toymoban.com/news/detail-539725.html

0 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
3 ldc #3 <hello world>
5 invokevirtual #4 <java/io/PrintStream.println : (Ljava/lang/String;)V>
8 return
			//添加say方法
        MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC,//方法修饰符号
                "say",//方法名
                "()V",//方法的描述符,用于描述方法的参数类型和返回值类型
                null,//方法泛型
                null//可能抛出的异常
        );

        //获取System.out
        methodVisitor.visitFieldInsn(
                Opcodes.GETSTATIC,//字段的类型
                "java/lang/System",//字段所属类的全限定类名
                "out",//指定字段
                "Ljava/io/PrintStream;"//字段描述信息
        );
        
        //加载常量
        methodVisitor.visitLdcInsn("hello world");

				
         methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL,//方法调用的操作码   
                "java/io/PrintStream",//方法的权限定类名
                "println",//方法名
                "(Ljava/lang/String;)V", //方法修饰符
                false);//方法调用者是否是接口
                
        methodVisitor.visitInsn(Opcodes.RETURN);
        methodVisitor.visitMaxs(2, 0);
        methodVisitor.visitEnd();

4.完成类的定义并创建实例调用目标方法

  			// 完成类的定义
        classWriter.visitEnd();
        // 将生成的字节码写入文件或加载到内存中
        byte[] bytecode = classWriter.toByteArray();


        ClassLoader classLoader = new ClassLoader() {
            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
                return defineClass(name, bytecode, 0, bytecode.length);
            }
        };
        // 加载并实例化Hello类
        Class<?> helloClass = classLoader.loadClass("Hello");
        Object helloObject = helloClass.getDeclaredConstructor().newInstance();
        // 调用say方法
        helloClass.getMethod("say").invoke(helloObject);

5.相关JVM指令

方法调用

  1. invokestatic:用于调用静态方法。该指令会根据方法的类名、方法名和方法描述符进行方法查找和调用。
  2. invokespecial:用于调用私有方法、构造方法和父类方法。该指令会根据方法的类名、方法名和方法描述符进行方法查找和调用。
  3. invokevirtual:用于调用实例方法。该指令会根据对象的类型和方法的签名进行方法查找和调用。
  4. invokeinterface:用于调用接口方法。该指令会根据接口的类型和方法的签名进行方法查找和调用。
  5. invokedynamic:用于调用动态方法。该指令会通过调用动态绑定方法来实现方法的调用

加载常量或数字

  1. ldc:将常量(包括字符串、整数、浮点数等)加载到操作数栈上。
  2. ldc_w:与ldc类似,但用于加载较大的常量(超过65535个字节)。
  3. bipush:将一个字节大小的整数常量(-128到127之间)加载到操作数栈上。
  4. sipush:将一个短整型常量(-32768到32767之间)加载到操作数栈上。
  5. iconst_:将整数常量(-1到5之间)加载到操作数栈上,其中为0到5之间的数字。 _
  6. fconst:将浮点数常量(0.0、1.0和2.0)加载到操作数栈上,其中为0到2之间的数字。
  7. dconst_:将双精度浮点数常量(0.0和1.0)加载到操作数栈上,其中为0或1。 _
  8. _ lconst_:将长整型常量(0和1)加载到操作数栈上,其中为0或1

到了这里,关于ASM Java字节码操作框架入门学习 输出Hello World的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用ASM在Android中进行字节码注入

    1.编译使用插件 这里自定义了一个插件用来对字节码进行操作 首先我们需要找到这个Gradle任务,双击进行编译打包 打包成功后会生成如下目录 然后我们需要在项目的gradle文件中进行引用 然后在application的model下的gradle中应用插件 这里在Activity中加了一个点击事件,这次是将

    2024年02月09日
    浏览(18)
  • 一、认识 JVM 规范(JVM 概述、字节码指令集、Class文件解析、ASM)

    JVM : Java Virtual Machine ,也就是 Java 虚拟机 所谓虚拟机是指:通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统。 即:虚拟机是一个计算机系统。这种计算机系统运行在完全隔离的环境中,且它的硬件系统功能是通过软件模拟出来的。 JVM 通

    2024年01月23日
    浏览(25)
  • 【Java基础教程】(四十四)IO篇 · 上:File类、字节流与字符流,分析字节输出流、字节输入流、字符输出流和字符输入流的区别~

    掌握 java.io包中类的继承关系 ; 掌握 File类的使用,并且可以通过File类进行文件的创建、删除以及文件夹的列表等操作; 掌握字节流或字符流操作文件内容,字节流与字符流的区别; 在 java.io 包中,如果要进行文件自身的操作 (例如:创建、删除等), 只能依靠 java.io.File 类完

    2024年02月15日
    浏览(16)
  • Tensorflow入门(2)——深度学习框架Tesnsflow & 线程+队列+IO操作 & 文件读取案例

    Tensorflow入门(1)——深度学习框架Tesnsflow入门 环境配置 认识Tensorflow 在训练样本的时候,希望读入的训练样本时有序的 • tf.FIFOQueue 先进先出队列,按顺序出队列 • tf.RandomShuffleQueue 随机出队列 FIFOQueue(capacity, dtypes, name=‘fifo_queue’) 创建一个以先进先出的顺序对元素进行排

    2024年02月17日
    浏览(18)
  • java~字节码操作Javassist

    Javassist是一个开源的Java字节码操作库,它提供了一组简单而强大的API,用于在运行时修改和生成Java字节码。Javassist的名称是\\\"Java Programming Assistant\\\"的缩写,它的目标是简化对字节码的操作,使开发人员能够更轻松地实现动态代码生成和修改。 Javassist的主要特点包括: 简单易

    2024年02月09日
    浏览(16)
  • Java字节码编程:从入门到精通

      Java是一种高级语言,其代码在编译后被转换为Java字节码文件。Java字节码文件包含了Java平台上的指令集,这些指令可以在Java虚拟机(JVM)上执行。因此,通过编写和操作字节码,我们可以在运行时动态地修改和扩展Java应用程序的行为。   Java字节码是Java编译器生成的

    2024年02月08日
    浏览(26)
  • 【Java】学习一门开发语言,从TA的Hello World开始

    欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《Java》序列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。 温馨提示:博主能力有限,理解水平有限

    2024年01月23日
    浏览(28)
  • C++输出Hello,World

    在 C 语言中输出 \\\"Hello, World\\\" 可以使用下面的代码: #include stdio.h int main() { printf(\\\"Hello, Worldn\\\"); return 0; } 代码的意思是:首先使用 #include stdio.h 告诉编译器我们要使用输入/输出函数,然后定义一个名为 main 的函数,在函数中使用 printf 函数来输出字符串 \\\"Hello, World\\\",最后使用

    2024年02月07日
    浏览(19)
  • FPGA入门学习笔记(十)Vivado设计状态机实现UART多字节数据发送

    使用串口发送5个字节数据到电脑 1、ADC采样的结果为12位,如何使用串口发送 2、16位数据,如何通过串口发送 3、多个字节的数据,如何通过串口发送 UART规定,发送的数据位只能有6、7、8位,若直接修改发送位数,接收模块将不适配。 两种情况: 1、没有开始发送(上一次的

    2024年02月12日
    浏览(20)
  • 【IMX6ULL驱动开发学习】01.编写第一个hello驱动+自动创建设备节点(不涉及硬件操作)

    目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结构体 int major = register_chrdev(0, \\\"name\\\", fops); 入口函数:调用

    2024年02月13日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包