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()