Java的反射机制 调用私有方法私有属性

直接上代码实现  后续有详细介绍,有感兴趣的可以看下

package xx.study.design.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 测试类
 * 1获取私有属性
 * 2获取私有对象 在获取私有对象的私有属性
 * 3获取方法
 */
public class ReflectDemo {
    public static void main(String[] args) {
        //初始化对象
        Clothes clothes=new Clothes("pleated skirt ");
        Person person=new Person("花花",clothes);
        //----------------已知对象person
        // 2获取对象属性

        Class  cla=person.getClass();

        try {
            Field[]  fields = cla.getDeclaredFields();
            for(Field field: fields){
                field.setAccessible(true); // 私有属性必须设置访问权限
                String name = field.getName();
                //1获取私有属性
                Object  resultValue = field.get(person);
                if("clothes".equals(name)){//获取私有对象 再获取私有对象的私有属性
                    Clothes clothes1=(Clothes)resultValue;
                    Class  clothsCla=clothes1.getClass();
                    Field[] clothesfields = clothsCla.getDeclaredFields();
                    for(Field clothesField: clothesfields){
                        clothesField.setAccessible(true); // 私有属性必须设置访问权限
                        String clothesName = clothesField.getName();
                        Object  clothesValue = clothesField.get(clothes1);
                        System.out.println(clothesName+":"+clothesValue);
                    }
                }
                // 这里可以编写你的业务代码
                System.out.println(name + ": " + resultValue);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 3获取调用私有方法
        try {
            Method[] methodArr= cla.getDeclaredMethods();
            for(Method method:methodArr){
                method.setAccessible(true);//私有属性必须设置访问权限
                if("sayHello".equals(method.getName())) {
                    method.invoke(person,"韩梅梅");//执行私有方法


                }
            }

        }catch (Exception e){

        }

 }
}

基础类

package xx.study.design.reflect;

public class Person {
    private final String name;
    private int age;
    private final Clothes clothes;
    public Person(String name, Clothes clothes) {
        this.name = name;
        this.clothes = clothes;
    }
    private void sayName(){
        System.out.println(this.name);
    }
    private void sayHello(String name){
        System.out.println(name+" 你好!!!");
    }
}

package xx.study.design.reflect;

/**
 * 衣服
 */
public class Clothes {
    //
    private final String pleatedSkir;

    public Clothes(String pleatedSkir) {
        this.pleatedSkir = pleatedSkir;
    }
}

一、Java反射简介
二、Class类
三、反射访问成员变量
四、反射访问方法
五、常见异常及问题

1 什么是反射


    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。
    这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

2 Java反射机制的功能


        1)在运行时判断任意一个对象所属的类;
        2)在运行时构造任意一个类的对象;
        3)在运行时判断任意一个类所具有的成员变量和方法;
        4)在运行时调用任意一个对象的方法;
        5)生成动态代理。

反射机制原理图

2 Class类

Java类均继承了Object类,因此,可以利用在Object类中已经定义的getClass()方法,返回一个类型为Class的对象。
 

常用方法
getMethods()——获取所有权限为public的方法
getMethod(String methodName,Class<?> …paramTypes)——根据方法名、各入参的类型,返回权限为public的指定方法
getDeclaredMethods()——获取所有方法
getDeclaredMethod(String methodName,Class<?> …paramTypes) ——根据方法名、各入参的类型,返回指定方法

同样,对于成员变量、内部类的访问方法,也分为限定权限public与否。

区别
    由此可见,在通过方法getMethods()依次获取权限为public的方法时,将包含从超类中继承的方法;而通过方法getDeclaredMethods()只是获得在本类中定义的方法。
    此规则同样适用于getFields()及getDeclaredFields()。

3 反射访问成员变量

在通过方法访问成员变量时,将返回Field类型的对象或数组。每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。
方法:
    getFields()
    getField(String name)
    getDeclaredFields()
    getDeclaredField(String name)

常用方法
    getName()——获得该成员变量的名称
    getType() ——获得表示该成员变量类型的Class对象
    get(Object obj) ——获得指定对象obj中成员变量的值,返回值为Object型
    set(Object obj,Object value) ——将指定对象obj中的成员变成的值设置为value
    getInt(Object obj) ——获得指定对象obj中类型为int的成员变量的值
    setInt(Object obj,int i) ——将指定对象obj中类型为int的成员变量的值设置为i
    getFloat(Object obj) ——获得指定对象obj中类型为float的成员变量的值
    setFloat(Object obj,float f) ——将指定对象obj中类型为float的成员变量的值设置为f
    getBoolean(Object obj) ——获得指定对象obj中类型为boolean的成员变量的值
    setBoolean(Object obj,boolean z) ——将获得指定对象obj中类型为boolean的成员变量的值设置为z
    setAccessible(Boolean flag) ——可以设置忽略权限限制直接访问private等私有权限的成员变量
    getModifiers() ——获得可以解析出该成员变量所采用的的修饰符的整数

set(Object obj,Object value)、setInt(Object obj,int i)、setFloat(Object obj,float f) 、setBoolean(Object obj,boolean z)仅能对权限为public、protected的成员变量进行操作。
    此时,需要利用setAccessible(Boolean flag)方法,设置为setAccessible(true),此时便可对private权限的成员变量进行修改。   

4 反射访问方法

在通过反射机制访问方法时,将返回Method类型的对象或数组。每个Method对象代表一个成员变量,利用Method对象可以操纵相应的成员变量。
方法:
    getMethods()
    getMethod (String name,Class<?>…paramTypes)
    getDeclaredMethods()
    getDeclaredMethod (String name,Class<?>…paramTypes)

如果是访问指定的方法,需要根据该方法的名称和入参的类型来访问。
    例如,访问一个名称为test、入参类型依次为int、String、boolean的方法,可以通过以下两种方式实现:
    1)objClass.getDeclaredMethod(“test”,int.class,String.class,boolean.class);
    2)objClass.getDeclaredMethod(“test”,new Class[]{int.class,String.class,boolean.class});

常用方法
    getName()——获得该方法的名称
    getParameterType() ——按照申明顺序,以Class数组的形式获得各个参数类型
    getReturnType() ——以Class对象的形式获得该方法的返回值
    getExceptionTypes()——以Class数组的形式获得该方法可能抛出的异常类型(包括try…catch、throws)
    invoke(Object obj,Object…args)——利用指定参数args,执行指定对象obj中的方法,返回值为Object类型
    isVarArgs()——查看该方法是否允许带有可变数量的参数,允许返回true
    getModifiers() ——获得可以解析出该成员变量所采用的的修饰符的整数

猜你喜欢

转载自blog.csdn.net/h4241778/article/details/107547949