上节里有关于asm的一些基本概念,好比:visit里的第一个类版本,方法的描述、引用描述等,下面将一一介绍。java
一个Java二进制的类文件,都有一个版本,对应于不一样的jdk版本。所以ASM中提供了几个常量来指定一个类的版,这些常量定义在org.objectweb.asm.Opcodes接口中,以下:web
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) 来得到,以下:jvm
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)); } }
运行结果:
spa
java/lang/String java/lang/Integer net/zq/test/ttt
咱们知道JAVA类型分为基本类型和引用类型,在JVM中对每一种类型都有与之相对应的类型描述code
基本类型描述以下:接口
java基本类型 |
jvm中的描述 |
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
引用类型描述以下: ip
通常引用类型为:“L该类型类描述符; ”。如:String类型的域描述符为 Ljava/lang/String; get
对于数组,其为:“ [其类型的域描述符;”。如: int[ ] 其描述符为[Istring
多维数组其则为: 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类中还提供了其余不少方法让咱们去了解一个类,有兴趣的能够能够深看一下,对于理解类会有很大帮助。