java的反射能夠繞過訪問權限,訪問到類的私有方法和成員。可能這點會引發安全性的討論。反射的使用幫助解決不少複雜的問題,其運行時的類型檢查,動態調用,代理的實現等,反射爲咱們寫程序帶來了很大的靈活性,不少功能都是基於反射。 利用反射還能夠訪問內部類、匿名內部類的私有屬性。 用java自帶的java -private 類名 反編譯命令能夠查看類的完整定義。(參考think in java) 下面舉例子說明。首先定義一個接口 Java代碼 public interface Ref { public void f(); } public interface Ref { public void f(); } 接口的實現類 Java代碼 public class RefImpl implements Ref { //實現接口方法 public void f() { System.out.println("public method f()"); } void g(String args){ System.out.println("package method g():" + args); } private void w(){ System.out.println("private method w()"); } } public class RefImpl implements Ref { //實現接口方法 public void f() { System.out.println("public method f()"); } void g(String args){ System.out.println("package method g():" + args); } private void w(){ System.out.println("private method w()"); } } 測試類 Java代碼 public class TestRef { public static void main(String[] args) { Ref ref = new RefImpl(); System.out.println(ref.getClass().getSimpleName()); //RefImpl類型 ref.f(); //調用接口方法 // ref.g(); //向上轉型後實現類添加的方法不能調用 if(ref instanceof RefImpl){ RefImpl ref1 = (RefImpl)ref; //類型識別後轉型 ref1.g("zhouyang"); // ref1.w(); //私有方法不能訪問 } //經過反射調用方法 try { Ref ref2 = new RefImpl(); Method m = ref2.getClass().getDeclaredMethod("f"); Method m1 = ref2.getClass().getDeclaredMethod("g", String.class);//有參的方法 Method m2 = ref2.getClass().getDeclaredMethod("w"); System.out.println("=============="); m.invoke(ref); //調用方法f() m1.invoke(ref, "yangzhou"); m2.setAccessible(true);///調用private方法的關鍵一句話 m2.invoke(ref); } catch (Exception e) { e.printStackTrace(); } //java的javap反編譯可以查看類的信息,-private 開關可以打開全部信息 //javap -private 類名 類必須是編譯成.calss 文件 //利用反射訪問私有成員,改變私有成員值,可是final域能夠訪問不可改變 PrivateField pf = new PrivateField(); // ps.ss; //私有成員不能訪問 //打印原來的成員值 pf.print(); try { //反射訪問和改變原來值 Field[] f = pf.getClass().getDeclaredFields(); for(int i=0;i<f.length;i++){ f[i].setAccessible(true); System.out.println(f[i].getType());//打印字段類型 System.out.println(f[i].get(pf)); //打印值 if("ss".equals(f[i].getName())){ f[i].set(pf, "hehe"); //修改爲員值 }else{ f[i].setInt(pf, 55); } } //從新打印修改後的成員值,final域值不變 pf.print(); } catch (Exception e) { e.printStackTrace(); } /*打印輸出的結果 * RefImpl public method f()