java asm获取常量class_Java 利用ASM读取变量值(Field value)问题研究

最近在学习Spring源码的过程中,遇到了spring-asm工程的重新打包的问题,于是突然就想研究一下asm这个开源字节码操作工具。秉承我的一贯风格,想到啥就立马学啥。

对于开源产品,我的一贯风格就是通过其官方提供的源码版本管理地址(svn/git等),直接下载最新代码,构建Java工程,直接通过工程依赖的方式研究学习。(你说这样跟依赖jar包并且绑定源码比有啥好处? 一般情况下差不多,最多就是,我可以随时更新代码,可以本地随意修改代码等等呵呵。个人喜好。)

ASM svn地址:

废话不多说,进入正题。我当时想研究的主要问题,就是想尝试通过ASM读取到class文件中声明的变量及其值(其实ASM的主要功能应该是动态生成字节码)。其他东西,我认为是可以触类旁通的。所以,我简单阅读了一下其官方文档,发现其tree API还是非常简单易懂,好上手的。所以,立即动手,我先新建了一个待读取的类。叫ForReadClass,内容如下:

/**

* @author lihzh

* @date 2012-4-21 下午10:18:46

*/

publicclassForReadClass {

finalintinit =110;

privatefinalInteger intField =120;

publicfinalString stringField ="Public Final Strng Value";

publicstaticString commStr ="Common String value";

String str = "Just a string value";

finaldoubled =1.1;

finalDouble D =1.2;

publicForReadClass() {

}

publicvoidmethodA() {

System.out.println(intField);

}

}

然后编写读取类如下:

/**

* @param args

* @author lihzh

* @date 2012-4-21 下午10:17:22

*/

ublic staticvoidmain(String[] args) {

try{

ClassReader reader = newClassReader("cn.home.practice.bean.ForReadClass");

ClassNode cn = newClassNode();

reader.accept(cn, 0);

System.out.println(cn.name);

List fieldList = cn.fields;

for(FieldNode fieldNode : fieldList) {

System.out.println("Field name: "+ fieldNode.name);

System.out.println("Field desc: "+ fieldNode.desc);

System.out.println("Filed value: "+ fieldNode.value);

System.out.println("Filed access: "+ fieldNode.access);

}

} catch(IOException e) {

e.printStackTrace();

}

代码很简单,并且语义也很清晰。Tree API,顾名思义是根据Class的结构,一层层读取其中的信息。但是,当我打印出值的时候,结果却让我大跌眼镜。所有vlaue都是 null。(注:第一次读取的时候ForReadClass中,只有三个变量,并且既不是final也不是基本数据类型)。

查看接口说明,发现其是从常量池中读取的值,并且要求filed类型必须是Integer/Double/....的。于是我又构造了几个final的和基本数据类型,如上所示。这次终于有值了。有值的都是final并且是基本数据类型的(String类型的必须是String s = "str"方式声明的,如果是new String("str")的也读取不到)。

21/212>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值