当前位置:编程学习 > JAVA >>

java中用反射访问私有方法和私有成员

 java的反射可以绕过访问权限,访问到类的私有方法和成员。可能这点会引起安全性的讨论。反射的使用帮助解决很多复杂的问题,其运行时的类型检查,动态调用,代理的实现等,反射为我们写程序带来了很大的灵活性,很多功能都是基于反射。
    利用反射还可以访问内部类、匿名内部类的私有属性。
    用java自带的java -private 类名 反编译命令可以查看类的完整定义。(参考think in java)
下面举例子说明。首先定义一个接口
Java代码 
public inte易做图ce Ref {  
    public void f();  

public inte易做图ce 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() 
          &nb

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,