动态访问私有属性

如何访问一个类的私有属性

这个类是在库函数中所写的,我们不能修改库函数的代码(即代码中添加getter() 方法,修改私有属性的方式是不可用的)。

使用反射的方法

首先,创建一个Exam 实体类。

public class Exam {
    // private 成员变量
    private String str1 = "private Attribute";
    
     // public  成员变量
    public String str2 = "public Attribute";

	// private Method
    private void fun1(){
        System.out.println("the private Method");
    }
	
   //public Method
    public void fun2(){
        System.out.println("the public Method");
    }
	
    //private Method With Argument
    private void fun3(String arg){
        System.out.println("the private Method With Argument");
    }
    
}

来看第一种测试方式

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test01 {
    public static void main(String[] args) {

        Exam e = new Exam();
        System.out.println("获取类中所有属性");
        
        // 通过反射来获取其所有fileds
        Field[] fields = e.getClass().getFields();
        for (Field field: fields){
            System.out.println(field);
        }
		
        // 通过反射来获取其所有 methods
        System.out.println("获取类中所有方法");
        Method[] methods = e.getClass().getMethods();
        for (Method method: methods){
            System.out.println(method);
        }

    }
}
---  这里只获取到了 public 成员变量 str2
//获取类中所有属性
//public java.lang.String Exam.str2

---  这里只获取到了 public 成员方法 fun2()
//获取类中所有方法
//public void Exam.fun2()
//public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//public final void java.lang.Object.wait() throws java.lang.InterruptedException
//public boolean java.lang.Object.equals(java.lang.Object)
//public java.lang.String java.lang.Object.toString()
//public native int java.lang.Object.hashCode()
//public final native java.lang.Class java.lang.Object.getClass()
//public final native void java.lang.Object.notify()
//public final native void java.lang.Object.notifyAll()
//
//Process finished with exit code 0

再来看后面一种测试的方式

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test02 {
    public static void main(String[] args) {

        Exam e = new Exam();

        try {
            // 通过属性名来获取对应的
            Field field1 = e.getClass().getDeclaredField("str1");
            Field field2 = e.getClass().getDeclaredField("str2");
			
            // 将其可见性  设定为true
            field1.setAccessible(true);
            
            // 					filed1 : private Attribute
            System.out.println(" filed1 : " +field1.get(e) );

            
            field1.set(e, "重新设定filed1 的值");
            
            // 					filed1 : 重新设定filed1 的值
            System.out.println(" filed1 : " +field1.get(e) );
            
            //					filed2 : public Attribute
            System.out.println(" filed2 : " +field2.get(e) );

            field2.set(e, "重新设定filed2的值");
            
            // 					filed1 : 重新设定filed1 的值
            System.out.println(" filed1 : " +field1.get(e) );
            // 					filed2 : 重新设定filed2的值
            System.out.println(" filed2 : " +field2.get(e) );

        } catch (NoSuchFieldException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        }


        try {
            Method method1 = e.getClass().getDeclaredMethod("fun1");
            method1.setAccessible(true);
            
            //   the private Method
            method1.invoke(e);

            Method method2 = e.getClass().getDeclaredMethod("fun2");
            method2.setAccessible(true);
            
            //the public Method
            method2.invoke(e);

            Method method3 = e.getClass().getDeclaredMethod("fun3", String.class);
            method3.setAccessible(true);
            
            //the private Method With Argument
            method3.invoke(e, "method3的参数");


        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }

    }
}


//可以看到。这样获访问到了一个类中的私有成员变量,并且也没有对该类进行改变。

同样,你也可以把这些方法封装成一个Util 工具类,通过static (设定为类方法)的方式来通过工具类访问其内部的属性与方法,当然,我要我们调用方法的时候传入属性名(参数名)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值