绕过Java中的可见性修饰符

时间:2017-01-26 19:06:43

标签: java

我需要访问第三方lib的私有和受保护方法。由于性能要求,我无法使用反射。也许有任何编译器设置允许我这样做?

1 个答案:

答案 0 :(得分:0)

一种方法是修改方法的修饰符然后使用允许操作字节码的库重新生成字节码,例如Javassist然后修补第3方库以用新的替换旧类生成的类。

例如,在课程org.apache.commons.io.FileUtils中有一种private static long sizeOf0(File file)类型的方法,假设我要将其设为public

使用Javassist,您可以按照下一步的步骤生成新的FileUtils.class

ClassPool pool = ClassPool.getDefault();
// Get the class org.apache.commons.io.FileUtils which is the class that 
// contains the method to modify
CtClass fileUtilsClass = pool.get("org.apache.commons.io.FileUtils");
// Get the class java.io.File which is the type of the parameter
CtClass fileClass = pool.get("java.io.File");
// Get the method to which we want to change the modifier
CtMethod method = fileUtilsClass.getDeclaredMethod("sizeOf0", new CtClass[]{fileClass});
// Set the modifier of the method to public
method.setModifiers(Modifier.PUBLIC);
// Write the new FileUtils.class in the user home directory following the package name
fileUtilsClass.writeFile(".");

从这里,您可以直接将旧FileUtils.class替换为jar并重命名jar以指示它不是原始路径而是修补的jar文件。例如,在这里,我可以将commons-io-2.5.jar重命名为commons-io-2.5-patch-01.jar