可以通过反射来调用那些非公共访问权限的方法。对于final域实际上在修改时是安全的。运行时系统人在不招聘异常的情况下接受任何修改的尝试,但是实际上不会发生任何修改。在类中留下这种后门,也许可以使我们能够解决某一特定类型的问题。
1 /** 2 * 通过反射来调用内部类的私有方法 3 */ 4 package typeinfo; 5 6 import java.lang.reflect.Field; 7 import java.lang.reflect.Method; 8 9 interface A{ 10 void f(); 11 } 12 class InnerA{ 13 private static class InnerB implements A{ 14 private int i=1; 15 private final String s="I'm totally safe."; 16 private void g() { 17 System.out.println("private g() "); 18 } 19 @Override 20 public void f() { 21 System.out.println("public f()"); 22 } 23 protected void h(){ 24 System.out.println("protected h()"); 25 } 26 void v(){ 27 System.out.println("package v()"); 28 } 29 public String toString(){ 30 return "i="+i+", s="+s; 31 } 32 } 33 public static A makeA(){ 34 return new InnerB(); 35 } 36 } 37 /** 38 * @author LYL 39 * 40 */ 41 public class InnerImplemetation { 42 /** 43 * 通过反射来调用对象的某一方法 44 * @param a 45 * @param methodName 46 * @throws Exception 47 */ 48 public static void callHiddenMethod(Object a,String methodName) throws Exception{ 49 Method method=a.getClass().getDeclaredMethod(methodName); 50 //设置为可访问 51 method.setAccessible(true); 52 method.invoke(a); 53 } 54 55 public static Field modifyPrivateField(Object a,String fieldName) throws Exception{ 56 Field field=a.getClass().getDeclaredField(fieldName); 57 field.setAccessible(true); 58 return field; 59 } 60 public static void main(String args[]) throws Exception{ 61 A a=InnerA.makeA(); 62 //显示出typeinfo.InnerA$InnerB 63 System.out.println(a.getClass()); 64 // 65 a.f(); 66 //通过反射来调用对象的隐藏方法 67 callHiddenMethod(a,"g"); 68 callHiddenMethod(a,"h"); 69 callHiddenMethod(a,"v"); 70 71 Field fieldI=modifyPrivateField(a,"i"); 72 fieldI.setInt(a,12); 73 System.out.println("Private field I:"+fieldI.getInt(a)); 74 Field field=modifyPrivateField(a,"s"); 75 field.set(a, "new value"); 76 System.out.println("final s:"+field.get(a)); 77 // 78 System.out.println(a); 79 } 80 }
输出:
class typeinfo.InnerA$InnerB
public f()
private g()
protected h()
package v()
Private field I:12
final s:new value
i=12, s=I'm totally safe.