上一篇文章,我们已体验到ASM的威力,那么结合上面的代码解释ASM是怎么执行的。

ClassWriter clazzWriter = new ClassWriter(0);  

首先看下官方文档对ClassWriter的描述:

A ClassVisitor that generates classes in bytecode form. More precisely this visitor generates a byte array conforming to the Java class file format. It can be used alone, to generate a Java class "from scratch", or with one or more ClassReader and adapter class visitor to generate a modified class from one or more existing Java classes

方法的栈长度和本地变量表长度用户自己计算(???怎么算);

clazzWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/sunchao/asm/HelloWorld", null, "java/lang/Object", null);  

解释下方法中参数的意思:

  • Opcodes.V1_5指定类的版本
  • Opcodes.ACC_PUBLIC表示这个类是public
  • “com/sunchao/asm/HelloWorld”类的全限定名称
  • 第一个null位置变量定义的是泛型签名,
  • “java/lang/Object”这个类的父类
  • 第二个null位子的变量定义的是这个类实现的接口
        MethodVisitor mv = clazzWriter.visitMethod(Opcodes.ACC_PUBLIC , "sayHello",
"()V" , null, null);//新增加一个方法
mv.visitCode();//启动访问字节码
//在java/lang/System上添加一个Ljava/io/PrintStream类型的字段‘out’
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Hello World!");//将常量池中的字符串常量加载到栈顶 ,输出字符串内容
//调用java/io/PrintStream中的println()方法
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.RETURN);//设置返回值
mv.visitMaxs(0, 0);//设置方法的栈和本地变量表的大
mv.visitEnd();//结束访问

代码中的注释,可以让我们看个大概了吧。

上面的代码中我们看到了如何使用ASM生成一个简单的JAVA类,里面使用到了很多的基本概念,比如:方法描述、引用描述等

一、类版本:

一个Java二进制的类文件,都有一个版本,因此ASM中提供了几个常量来指定一个类的版,这些常量定义在org.objectweb.asm.Opcodes接口中,如下:

// versions  

    int V1_1 = 3 << 16 | 45;
int V1_2 = 0 << 16 | 46;
int V1_3 = 0 << 16 | 47;
int V1_4 = 0 << 16 | 48;
int V1_5 = 0 << 16 | 49;
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;

二、JVM内部名字:

在Java二进制文件中使用的是JVM的内部名字,而不是我们所熟悉的以“.”分割的全限定名,内部名字是以“/”替代“.”的全名,例如:java.lang.String在JVM中的内部名字是java/lang/String。在ASM中可以使用org.objectweb.asm.Type类中的静态方法getInternalName(final Class c) 来获得,如下:

public class InternalNameTransform {
public static void main(String[] args) {
System.out.println(Type.getInternalName(String.class));
System.out.println(Type.getInternalName(Integer.class));
System.out.println(Type.getInternalName(InternalNameTransform.class));
}
}

运行结果:

java/lang/String
java/lang/Integer
com/sunchao/asm/InternalNameTransform

三、类型描述:

我们知道JAVA类型分为基本类型和引用类型,在JVM中对每一种类型都有与之相对应的类型描述,如下表:

Java类型 JVM中的描述
boolean Z
char C
byte B
short S
int I
float F
long J
double D
Object Ljava/lang/Object;
int[] [I
Object[][] [[Ljava/lang/Object;

在ASM中要获得一个类的JVM内部描述,可以使用org.objectweb.asm.Type类中的getDescriptor(final Class c)方法,如下:

public class TypeDescriptors {
public static void main(String[] args) {
System.out.println(Type.getDescriptor(TypeDescriptors.class));
System.out.println(Type.getDescriptor(String.class));
} }

运行结果:

Lcom/sunchao/asm/TypeDescriptors;
Ljava/lang/String;

四、方法描述:

在Java的二进制文件中,方法的方法名和方法的描述都是存储在Constant pool中的,且在两个不同的单元里。因此,方法描述中不含有方法名,只含有参数类型和返回类型,如下:

方法描述,在类中的 方法描述,在二进制文件中的
void a(int i,float f) (IF)V
void a(Object o) (Ljava/lang/Object;)V
int a(int i,String s) (ILjava/lang/String;)I
int[] a(int[] i) ([I)[I
String a() ()Ljava/lang/String;

获取一个方法的描述可以使用org.objectweb.asm.Type.getMethodDescriptor方法,如下:

public class MethodDescriptors {
public static void main(String[] args) throws Exception {
Method m = String.class.getMethod("substring", int.class);
System.out.println(Type.getMethodDescriptor(m));
} }

运行结果:

(I)Ljava/lang/String;  

其实在org.objectweb.asm.Type类中提供了很多方法。

原文请见:http://exceptioneye.iteye.com/category/253313

再叙ASM的更多相关文章

  1. EntityFramework Core Raw Query再叙注意事项

    前言 最近一直比较忙没有太多时间去更新博客,接下来会一直持续发表相关内容博客,上一篇我们讲到了EF Core中的原始查询,这节我们再来叙述一下原始查询,本文是基于在项目当中用到时发现的问题. 话题 我 ...

  2. EntityFramework Core Raw Query再叙注意事项后续

    前言 话说通过EntityFramwork Core进行原始查询又出问题,且听我娓娓道来. EntityFramework Core Raw Query后续 当我们进行复杂查询时我们会通过原始查询来进 ...

  3. 再叙TIME_WAIT

    之所以起这样一个题目是因为很久以前我曾经写过一篇介绍TIME_WAIT的文章,不过当时基本属于浅尝辄止,并没深入说明问题的来龙去脉,碰巧这段时间反复被别人问到相关的问题,让我觉得有必要全面总结一下,以 ...

  4. [转] 再叙TIME_WAIT

    http://huoding.com/2013/12/31/316 之所以起这样一个题目是因为很久以前我曾经写过一篇介绍TIME_WAIT的文章,不过当时基本属于浅尝辄止,并没深入说明问题的来龙去脉, ...

  5. 再叙Java反射

    Java中的反射 本文为反射的基础知识部分. 能够分析类能力的程序被称为反射(reflective). 反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,容许程序在运行时加载.探知. ...

  6. rhel5.8安装oracle 10g ASM

    1.所有的配置和文件系统一样 2.规划: 加了8块小盘,ASM为了实验使用asmlib驱动(rhel6不再支持asmlib驱动),裸设备的2种方法(rowdevice和udev) 三块盘使用asmli ...

  7. ASM文件系统

    1.确认数据库版本 2.个人理解的存储解决方案的发展趋势 2.1图示说明 2.2图示描述 如上图我们描述了在不同时期的IT行业(数据库)出现的存储文件系统,下面我们将分别说明: ü  裸设备:所谓裸设 ...

  8. Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)

    <Windows Azure Platform 系列文章目录> 因为我们在上一节中: Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1) 已经创建了Azure V ...

  9. RAW+ASM 的RAC 安装文档

    实验平台:Oracle 10gR2 RAC + RHEL 4.0 +VMWare GSX 3.2.0 安装步骤: 1.安装前准备及OS安装配置 2.安装Oracle 10gR2 clusterware ...

随机推荐

  1. Redis学习笔记(二)Redis支持的5种数据类型的总结之String和Hash

    引言 在Redis学习笔记(一)中我们已经会安装并且简单使用Redis了,接下来我们一起来学习下Redis支持的5大数据类型. 简介 Redis是REmote DIctionary Server(远程 ...

  2. winform展示Unity3D文件(支持动态改变文件路径)

    winform下展示Unity3D文件可以支持对Unity3D实现的模块进行包装,以及在其他的项目中需要展示Unity3D的界面时候,恰到适宜地进行打开展示,这里我展示如何使用winform打开Uni ...

  3. TPFrame框架之robot模块的基本使用

    经过几天的努力,基本功能版已经完成,有待大家验证... robot插件主要的功能是帮助我们写部分代码的基本,目前阶段已经实现后台curd数据管理的基本操作,更多功能待续... 1.首先下载robot插 ...

  4. [转]OpenLiveWriter 代码插件

    插件地址链接:http://pan.baidu.com/s/1jHFDtbS 密码:ax31 将文件解压,放在路径下面 重启应用后,如图

  5. NoSQL:Linux操作memcached

    一 NoSQL简介 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付 ...

  6. python检测404页面

    某些网站为了实现友好的用户交互,提供了一种自定义的错误页面,而不是显示一个大大的404 ,比如CSDN上的404提示页面如下: 这样虽然提高了用户体验,但是在编写对应POC进行检测的时候如果只根据返回 ...

  7. Error: Your project contains C++ files but it is not using a supported native build system

    我在编写有关JNI的代码的时候回报这个错误,我在网上搜了相关的资料后,找到了一篇文章解决了这个问题,点击这里查看这篇文章,我在照着这篇文章尝试的时候,总有一些错误,现在我把自己详细的解决流程贴出来,供 ...

  8. 2、ABPZero系列教程之拼多多卖家工具 更改数据库为Mysql

    因为要部署项目到云服务器,不想在服务器上装SqlServer,所以需要把项目改为Mysql. 项目初始化 1.下载项目压缩包,前面文章已经说到,可以加群到群文件里下载.解压缩下载的项目源码,使用VS2 ...

  9. 【转】jar包和war包的介绍和区别

    JavaSE程序可以打包成Jar包(J其实可以理解为Java了),而JavaWeb程序可以打包成war包(w其实可以理解为Web了).然后把war发布到Tomcat的webapps目录下,Tomcat ...

  10. 安装配置Oracle 12c RAC

    http://www.lab128.com/rac12_installation_using_vb/article_text.html