Java利用ASM读取变量值(Field value)问题研究
作者:网络转载 发布时间:[ 2013/2/21 9:45:13 ] 推荐标签:
看似问题解决了一个,但是接下来的问题是,那些非final和非基本数据类型的变量的值该如何获取呢?这个问题着实困扰了许久,google了一大顿(ps:还是翻墙的google)也没找到答案,网上用ASM的多是用其生成字节码。不死心我的决定自己研究。在网上的一片博客中,我注意到一个样例,给出的是用MethodVisitor来改变一个变量的值。于是,我立即把目光从FieldNode转移到MethodNode之上。通过观察变异后class字节码,几番周折,有了如下代码:
/**
* @param args
* @author lihzh
* @date 2012-4-21 下午10:17:22
*/
public static void main(String[] args) {
try {
ClassReader reader = new ClassReader(
"cn.home.practice.bean.ForReadClass");
ClassNode cn = new ClassNode();
reader.accept(cn, 0);
List<MethodNode> methodList = cn.methods;
for (MethodNode md : methodList) {
System.out.println(md.name);
System.out.println(md.access);
System.out.println(md.desc);
System.out.println(md.signature);
List<LocalVariableNode> lvNodeList = md.localVariables;
for (LocalVariableNode lvn : lvNodeList) {
System.out.println("Local name: " + lvn.name);
System.out.println("Local name: " + lvn.start.getLabel());
System.out.println("Local name: " + lvn.desc);
System.out.println("Local name: " + lvn.signature);
}
Iterator<AbstractInsnNode> instraIter = md.instructions.iterator();
while (instraIter.hasNext()) {
AbstractInsnNode abi = instraIter.next();
if (abi instanceof LdcInsnNode) {
LdcInsnNode ldcI = (LdcInsnNode) abi;
System.out.println("LDC node value: " + ldcI.cst);
}
}
}
MethodVisitor mv = cn.visitMethod(Opcodes.AALOAD, "<init>", Type
.getType(String.class).toString(), null, null);
mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(String.class), "str", Type
.getType(String.class).toString());
System.out.println(cn.name);
List<FieldNode> 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);
if (fieldNode.visibleAnnotations != null) {
for (AnnotationNode anNode : fieldNode.visibleAnnotations) {
System.out.println(anNode.desc);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
从AbstractInsnNode中,我终于取到了其他变量的值。
--------------------------------------------------------------------------------
总结:之所以大费周章,主要还是因为我对Class字节码的不熟悉,网上之所以少有我遇到的问题,我想一方面是由于,我的使用场景与大多数人不同,另一方面可能是由于使用ASM的人大多对字节码还算了解,不会犯我这样的错误。:)
呵呵,总而言之,虽然耗费一定的时间,总归还有收获,心满意足。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11