asm学习2-java类在asm里的基本描述

上节里有关于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中的描述
booleanZ
byteB
charC
shortS
intI
longJ
floatF
doubleD

引用类型描述如下: 

 一般引用类型为:“L该类型类描述符;  ”。如:String类型的域描述符为 Ljava/lang/String;  

 对于数组,其为:“ [其类型的域描述符;”。如: int[ ]     其描述符为[I

多维数组其则为: N个[该类型的域描述符 , N代表的是几维数组。如:int  [ ][ ] 其描述符为[[I

java引用类型jvm中的描述
StringLjava/lang/String;
ObjectLjava/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;

方法描述

分两部分:

  1. 括号中参数部分:用括号括起来里面的参数描述

  2. 返回值类型部分:返回值值类型的描述符

  3. 综合在一起即为:(参数的描述符-按原顺序)返回类型描述符

    1. 如:void a(int i,float f) 表示为 (IF)V

  4. 对于无返回值的,用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类中还提供了其他很多方法让我们去了解一个类,有兴趣的可以可以深看一下,对于理解类会有很大帮助。

转载于:https://my.oschina.net/u/914655/blog/376082

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值