• java中用反射访问私有方法和私有成员[转]


    转自: http://zhouyangchenrui.iteye.com/blog/470521

        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()");  
        }  
    }  

    测试类:

    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    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);  
        }  
    }  
  • 相关阅读:
    QPS计算
    Burp学院-信息泄露
    Burp学院-OS命令注入
    Burp学院-SQL注入
    时间格式转换 日期转换
    K8s 1.20x版本nfs动态存储报错 persistentvolume-controller waiting for a volume to be created, either by external provisioner "qgg-nfs-storage" or manually created by system administrator
    K8Snode的自定义状态信息
    kubernetes之node资源紧缺时pod驱逐机制
    K8Snode最大pod数量
    阿里云域名白名单访问限制
  • 原文地址:https://www.cnblogs.com/lionfight/p/3215345.html
Copyright © 2020-2023  润新知