标签:
上节里有关于asm的一些基本概念,比如:visit里的第一个类版本,方法的描述、引用描述等,下面将一一介绍。
一个Java二进制的类文件,都有一个版本,对应于不同的jdk版本。因此ASM中提供了几个常量来指定一个类的版,这些常量定义在org.objectweb.asm.Opcodes接口中,如下:
asm中类版本标识 | 对应jdk版本 |
public static final int V1_1 = 196653; | |
public static final int V1_2 = 46; | 1.2 |
public static final int V1_3 = 47; | 1.3 |
public static final int V1_4 = 48; | 1.4 |
public static final int V1_5 = 49; | 1.5 |
public static final int V1_6 = 50; | 1.6 |
public static final int V1_7 = 51; | 1.7 |
public static final int V1_8 = 52; | 1.8 |
在Java二进制文件中使用的是JVM的内部名字,而不是我们所熟悉的以“.”分割的全限定名,内部名字是以“/”替代“.”的全名。例如:java.lang.String在JVM中的内部名字是java/lang/String。
在ASM中可以使用org.objectweb.asm.Type类中的静态方法getInternalName(final Class c) 来获得,如下:
package net.zq.test; import org.objectweb.asm.Type; public class ttt { 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(ttt.class)); } }
运行结果:
java/lang/String java/lang/Integer net/zq/test/ttt
我们知道JAVA类型分为基本类型和引用类型,在JVM中对每一种类型都有与之相对应的类型描述
基本类型描述如下:
java基本类型 |
jvm中的描述 |
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
引用类型描述如下:
一般引用类型为:“L该类型类描述符; ”。如:String类型的域描述符为 Ljava/lang/String;
对于数组,其为:“ [其类型的域描述符;”。如: int[ ] 其描述符为[I
多维数组其则为: N个[该类型的域描述符 , N代表的是几维数组。如:int [ ][ ] 其描述符为[[I
java引用类型 | jvm中的描述 |
String | Ljava/lang/String; |
Object | Ljava/lang/Object; |
int[] | [I |
float[] | [F |
String[] | [Ljava/lang/String; |
Object[] | [Ljava/lang/Object; |
int[ ][ ] | [[I |
float[ ][ ] | [[F |
在ASM中要获取类的内部描述,可以使用org.objectweb.asm.Type类中的getDescriptor(final Class c)方法,如下:
package net.zq.test; import org.objectweb.asm.Type; public class ttt { public static void main(String[] args) { System.out.println(Type.getDescriptor(ttt.class)); System.out.println(Type.getDescriptor(String.class)); } }
运行结果:
Lnet/zq/test/ttt; Ljava/lang/String;
分两部分:
括号中参数部分:用括号括起来里面的参数描述
返回值类型部分:返回值值类型的描述符
综合在一起即为:(参数的描述符-按原顺序)返回类型描述符
如:void a(int i,float f) 表示为 (IF)V
对于无返回值的,用V(表示void)表示
如下:
java层的方法描述 |
二进制文件中的方法描述 |
String test() |
Ljava/lang/String; |
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 |
void set (byte[ ] bytes) | ([B)V |
获取一个方法的描述,在ASM用org.objectweb.asm.Type.getMethodDescriptor来获取,如下:
package net.zq.test; import org.objectweb.asm.Type; public class ttt { public static void main(String[] args) throws NoSuchMethodException, SecurityException { java.lang.reflect.Method m = String.class.getMethod("substring", int.class); System.out.println(Type.getMethodDescriptor(m)); } }
运行结果 如下:
(I)Ljava/lang/String;
在org.objectweb.asm.Type类中还提供了其他很多方法让我们去了解一个类,有兴趣的可以可以深看一下,对于理解类会有很大帮助。
标签:
原文地址:http://my.oschina.net/u/914655/blog/376082