Java ASM介绍
一、什么是ASM
首先看下官方中的说明 ASM a very small and fast Java bytecode manipulation framework。
ASM是一个JAVA字节码分析、创建和修改的开源应用框架。它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵活的操作字节码的方式。ASM相当小巧,并且它有更高的执行效率,是BCEL的7倍,SERP的11倍以上(摘自网络,具体没有测试)。目前ASM已被广泛的开源应用架构所使用,例如:Spring、Hibernate等。
二、ASM能做什么
我们都知道,一般情况下,Class文件是通过javac编译器产生的,然后通过类加载器加载到虚拟机内,再通过执行引擎去执行。现在我们可以通过ASM的API直接生成符合Java虚拟机规范的Class字节流,这样,ASM做的事情一定程度上正是javac解释器做的工作。
可以说ASM分析一个类、从字节码角度创建一个类、修改一个已经被编译过的类文件。
那么,我们就可以通过ASM来实现诸如代码生成,代码混淆,代码转换等等以字节码为操作目标的工作
三、Java二进制(class)文件的格式
要想驾驭ASM,先要了解一下JAVA的CLASS文件格式。JAVA的CLASS文件通常是树型结构。根节点包含以下元素:
- ConstantPool:符号表;
- FieldInfo:类中的成员变量信息;
- MethodInfo:类中的方法描述;
- Attribute:可选的附加节点。
FieldInfo节点包含成员变量的名称,诸如public,private,static等的标志。
ConstantValue属性用来存储静态的不变的成员变量的值。
Deprecated和Synthetic被用来标记一个成员变量是不被推荐的或由编译器生成的。
MethodInfo节点包含方法的名称,参数的类型和和它的返回值,方法是公有的,私有的或静态的等标志。
MethodInfo包含可选的附加属性,其中最重要的是Code属性,它包含非抽象的方法的代码。
Exceptions属性包含方法将抛出的Exception的名称。
Deprecated和Synthetic属性的信息同上面的FieldInfo的定义一样。
根节点的可选属性有SourceFile,InnerClasses和Deprecated。
SourceFile用来存储被编译成字节码的源代码文件的原始名称;
InnerClasses存储内部类的信息。由于这些属性的存在,java 的类格式是可以扩展的,也就是说可以在一个class中 附加一些非标准的属性, java虚拟机会忽略这些不可识别的属性,正常的加载这个class。
ConstantPool是一个由数字或字符串常量的索引组成的队列,或由此类的树的其他节点引用的,由其他对象创建的被引用常量的索引组成的队列。这个表的目标是为了减少冗余。例如,FieldInfo节点不包含节点的名称,只包含它在这一表中的索引。同样的,GETFIELD和PUTFIELD不直接包含成员变量的名称,只包含名称的索引。
初试ASM(hello world):
package com.sunchao.asm; import java.io.File;
import java.io.FileOutputStream; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; /**
* the hello world byte code generate
* by asm.
* @author Administrator
*
*/
public class HelloWorld { public static void main(String args[]) throws Exception {
ClassWriter classWriter = new ClassWriter(0);
String className = "com/sunchao/asm/HelloWorld";
classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null,
"java/lang/Object", null); MethodVisitor initVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
"()V", null, null);
initVisitor.visitCode();
initVisitor.visitVarInsn(Opcodes.ALOAD, 0);
initVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
"V()");
initVisitor.visitInsn(Opcodes.RETURN);
initVisitor.visitMaxs(1, 1);
initVisitor.visitEnd(); MethodVisitor helloVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "sayHello",
"()V;", null, null);
helloVisitor.visitCode();
helloVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out",
"Ljava/io/PrintStream;");
helloVisitor.visitLdcInsn("hello world!");
helloVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream",
"println", "(Ljava/lang/String;)V");
helloVisitor.visitInsn(Opcodes.RETURN);
helloVisitor.visitMaxs(1, 1);
helloVisitor.visitEnd(); classWriter.visitEnd();
byte[] code = classWriter.toByteArray();
File file = new File("D:\\HelloWorld.class");
FileOutputStream output = new FileOutputStream(file);
output.write(code);
output.close();
} }

Java ASM介绍的更多相关文章
- Android下HelloWorld项目的R.java文件介绍
R.java文件介绍 HelloWorld工程中的R.java文件 package com.android.hellworld; public final class R { public s ...
- 深入Java虚拟机读书笔记第一章Java体系结构介绍
第1章 Java体系结构介绍 Java技术核心:Java虚拟机 Java:安全(先天防bug的设计.内存).健壮.平台无关.网络无关(底层结构上,对象序列化和RMI为分布式系统中各个部分共享对象提供了 ...
- Oracle asm介绍和安装linux+oracle10g+asm过程
Oracle asm介绍和安装linux5.2+oracle10g+asm过程 1)ASM(自动存储管理)的来由: ASM是Oracle 10g R2中为了简化Oracle数据库的管理而推出来 ...
- java集合介绍(List,Set,Map)
前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...
- Java学习介绍
Java版本介绍 JavaME:微型版,用于开发小型设备.智能卡.移动终端应用(使用率较低) JavaSE:标准版,用于创建桌面应用(企业用JavaSE创建桌面应用较少) JavaEE:企业版,用于创 ...
- 流行的9个Java框架介绍: 优点、缺点等等
流行的9个Java框架介绍: 优点.缺点等等 在 2018年,Java仍然是世界上最流行的编程语言.它拥有一个巨大的生态系统,在全世界有超过900万Java开发人员.虽然Java不是最直接的语言,但是 ...
- Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试【转】
Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试[转] 本文是本人前一段时间做一个简单Java监控工具调研总 ...
- java JNI介绍
java JNI介绍 目录 java JNI介绍 1. Java调用C++代码 2.C++代码调用java代码 JNI是Java Native Interface的全称. oracle文档中是这样描述 ...
- Java秘诀!Java逻辑运算符介绍
运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...
随机推荐
- 在vim中使用zencoding/Emmet
zencoding在vim上的插件已经改名为Emmet.vim 1. 安装,推荐使用vundle插件管理器安装,在~/.vimrc中,添加:Bundle 'Emmet.vim',输入命令vim +Bu ...
- 纯css去实现loading动画效果图
当项目中加载内容慢的的时候,需要显示一个loading动画效果图 之前我们使用的是一圈点点旋转的效果,现在设计修改为,如下gif图片效果-------------------------------- ...
- VMware仅主机模式虚拟机无法ping通物理机
问题描述 在VMware Workstation中新建了一个虚拟机CentOS7,网络适配器选择的是"仅主机模式",结果,物理机ping不通虚拟机,虚拟机也ping不通物理机. 原 ...
- Mvc项目部署IIS报错:没有为请求的URL配置默认文档,并且没有在服务器设置目录浏览
问题原因: 1.iis是在安装完.net framework 之后才安装的,需要进行iis注册,开始--运行--cmd,打开命令行提示符,输入命令如下 C:\Windows\Microsoft.NET ...
- PE文件详解(三)
本文转自小甲鱼的PE文件详解系列传送门 PE文件到内存的映射 在执行一个PE文件的时候,windows 并不在一开始就将整个文件读入内存的,二十采用与内存映射文件类似的机制. 也就是说,windows ...
- 表迁移工具的选型-xtrabackup的使用
1.1. 场景 有的时候test人员可能需要在测试库上比较新的数据,这时候只能是从生产库上面去那了.如果是小表还好实用mysqldump/mysqlpump就可以轻松的解决.但是,如果遇到了大表这将是 ...
- Spring Boot快速入门(一): Hello Spring Boot
原文地址:https://lierabbit.cn/articles/2 一.准备工作 java环境:jdk 1.8 开发工具:idea 二.创建项目 打开idea 点击Create New Proj ...
- PHP获取DHCP分配的本机IP
在搭建本地环境的时候,需要用到多个设备,有服务器.打印机连接接设备等.因为DHCP动态分配IP,所以每次重连都会发生IP地址的变更. 解决办法就是将每个设备的本机IP上传到统一的地方保存.因为使用RE ...
- ASP.NET Core Razor中处理Ajax请求
如何ASP.NET Core Razor中处理Ajax请求 在ASP.NET Core Razor(以下简称Razor)刚出来的时候,看了一下官方的文档,一直没怎么用过.今天闲来无事,准备用Rozor ...
- JS 监听浏览器各个标签间的切换
以前看到过一些网页,在标签切换到其它地址时,网页上的标题上会发生变化,一直不知道这个是怎么做的,最近查了一些资料才发现有一个 visibilitychange 事件就可以搞定,这里将介绍一下页面可见性 ...