清单 9. 使用字节码访问类 A
//修改变量的修饰符public class AccessClassAdapter extends ClassAdapter { public AccessClassAdapter(ClassVisitor cv) { super(cv); } public FieldVisitor visitField(final int access, String name, final String desc, final String signature, final Object value) { int privateAccess = access; //找到名字为number的变量 if (name.equals("number")) privateAccess = Opcodes.ACC_PUBLIC; //修字段的修饰符为public:在职责链传递过程中替换调用参数 return cv.visitField(privateAccess, name, desc, signature, value); } public static void main(String[] args) throws Exception { ClassReader cr = new ClassReader("A"); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassAdapter classAdapter = new AccessClassAdapter(cw); cr.accept(classAdapter, ClassReader.SKIP_DEBUG); byte[] data = cw.toByteArray(); //生成新的字节码文件 File file = new File("A.class"); FileOutputStream fout = new FileOutputStream(file); fout.write(data); fout.close(); }}
执行完该类,将产生一个新的 A.class 文件。
测试类测试 method 方法,先对变量进行置初值,然后就可以像其他单元测试一样,对 method 方法进行测试。
回页首
方法对比
方法 修饰符 使用难度 缺陷
protected 缺省 private
方法一:修改访问权限修饰符 是 是 是 低,有java编程基础即可。 由于需要修改源代码,虽然是同包可见,也会带来一些封闭性的问题。
方法二:利用安全性管理器 是 是 是 中,需要了解java安全性管理器及反射机制。 一些对代码安全有要求的程序,程序员并没有修改security manager的权限,此时,安全管理器方法失效。
方法三:使用模仿对象 是 是 否 较高,需要了解设计模式和待测对象的内部实现细节。 由于模仿对象要求伪类必需和待测类是继承与被继承的关系,所以当源码以private关键字修饰时,此方法失效。
方法四:利用字节码技术 是 是 是 高,需要操作和改写类部分的字节码。 学习成本高,需要了解Java字节码技术。
44/4<1234