欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java中用反射访问私有方法和私有成员,java私有成员,java的反射可以绕过访

来源: javaer 分享于  点击 40432 次 点评:62

java中用反射访问私有方法和私有成员,java私有成员,java的反射可以绕过访


java的反射可以绕过访问权限,访问到类的私有方法和成员。可能这点会引起安全性的讨论。反射的使用帮助解决很多复杂的问题,其运行时的类型检查,动态调用,代理的实现等,反射为我们写程序带来了很大的灵活性,很多功能都是基于反射。

利用反射还可以访问内部类、匿名内部类的私有属性。

用java自带的java -private 类名 反编译命令可以查看类的完整定义。(参考think in java)

下面举例子说明。首先定义一个接口

public interface Ref {      public void f();  }  

接口的实现类

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 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()             package method g():zhouyang             ==============             public method f()             package method g():yangzhou             private method w()             ss:nihao             count:1             num:47             class java.lang.String             nihao             int             1             int             47             ss:hehe             count:55             num:47          */      }  }  class PrivateField {      private String ss = "nihao";      private int count = 1;      private final int num = 47;      void print(){          System.out.println("ss:" + ss);          System.out.println("count:" + count);          System.out.println("num:" + num);      }  }  
相关栏目:

用户点评