欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过反射获取类对象的属性和方法及破坏私有属性

程序员文章站 2024-01-21 14:33:10
...

1.Class类中要掌握的方法

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

public class Test02 {
    public static void main(String[] args) throws Exception {
        Class<?> person = Class.forName("Person");
        // 获得类对象的一个属性
        Field name = person.getDeclaredField("name");
        System.out.println(name);
        // 获得一个具体的方法
        Method getName = person.getDeclaredMethod("getName", new Class[]{});
        System.out.println(getName);
        Method setName = person.getDeclaredMethod("setName", new Class[]{String.class});
        System.out.println(setName);
        //获得构造器
        Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});

        // 获得带参数的构造器(参数得必须跟类对象的构造方法参数一致)
        Constructor<?> constructor1 = person.getDeclaredConstructor(Integer.class, String.class, String.class);
        System.out.println(constructor1);
    }
}

2.通过反射的方式赋值

 

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

public class Test03 {
    public static void main(String[] args) throws Exception {
        Class<?> person = Class.forName("Person");
        //获得构造器
        Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
        // 根据类的默认构造器来获得一个对象
        Object o = constructor.newInstance(new Object[]{});
        System.out.println(o);
        
        // 根据类的有参构造器来获得一个对象
//        Constructor<?> constructor1 = person.getDeclaredConstructor(Integer.class, String.class, String.class);
//        Object o1 = constructor1.newInstance(1, "李四", "男");
//        System.out.println(o1);
        // 获得类的所有方法
        Method[] methods = person.getDeclaredMethods();
        for (Method m : methods) {
            // 获得方法的名字
            String name = m.getName();
            // 获得是否以set开始
            boolean startsWith = name.startsWith("set");
            if(startsWith) {
                // 获得到了set字符串后面的值
                String fieldName = name.substring(3);
                /*
                * 获得属性的名字
                * 因为我们的get set方法对应的属性名称第一位是大写,所以通过substring进行截取并转换成小写,最后拼上后面的半截属性的名称
                * 则拼接出我们类对象的属性名称
                * 然后通过getDeclaredField方法来获得所对应的属性也就是   private 类型  属性名称
                * */
                fieldName = fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1);
                // 获得方法所对应的属性
                Field field = person.getDeclaredField(fieldName);

                /*
                * 获得属性的具体类型,获得属性对应的类型
                * 知道属性之后还得知道它具体类型
                * */
                Class<?> type = field.getType();
                if(type == Integer.class) {
                    // 反射调用set方法并赋值
                    m.invoke(o, 5);
                }

                if(type == String.class && "name".equals(fieldName)) {
                    m.invoke(o, "李四");
                }

                if(type == String.class && "gender".equals(fieldName)) {
                    m.invoke(o, "男");
                }

            }
        }
        System.out.println(o);
    }
}

3.通过反射调用get方法及调用静态方法

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

public class Test04 {
    public static void main(String[] args) throws Exception {
        Class<?> person = Class.forName("Person");
        // 获得构造器
        Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
        // 根据类的默认构造器来获得一个对象
        Object o = constructor.newInstance(new Object[]{});
        // 获得name的set方法
        Method setName = person.getDeclaredMethod("setName", String.class);
        // 使用反射给name设置值
        Object invoke = setName.invoke(o, new Object[]{"张三"});

        // 获得name的get方法
        // Method getName = person.getDeclaredMethod("getName", new Class[]{});

        // 这样也行,但是不建议这样使用
        // Method getName = person.getDeclaredMethod("getName", null);

        // 也可这样使用
        Method getName = person.getDeclaredMethod("getName");

        // 使用反射调用getName获得类对象属性的值
        Object invoke1 = getName.invoke(o, new Object[]{});
        System.out.println(invoke1);

        // 反射调用静态方法
        Method printInfo = person.getDeclaredMethod("printInfo");
        // 因为该方法并没有返回值,所以直接可这样调用
        printInfo.invoke(null, null);
        printInfo.invoke(null);

    }
}

4.通过反射调用私有属性设置权限

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

public class Test05 {
    public static void main(String[] args) throws Exception {
        Class<?> person = Class.forName("Person");
        // 获得构造器
        Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
        Object o = constructor.newInstance(new Object[]{});
        // 根据方法名字获得属性对象
        Field name = person.getDeclaredField("name");
        /*
        * 这样直接设置值,会报错,因为我们的类对象的属性修饰符是私有的
        * 所以这就涉及到了设置权限的问题
        * setAccessible破坏掉私有属性
        * 静态方法也可设置权限
        * */
        name.setAccessible(true);
        name.set(o, "张三");

        // 获得属性的类型
        Class<?> type = name.getType();
        System.out.println(type);

    }
}

类对象如下:

public class Person {
    private Integer id;
    private String name;
    private String gender;

    public Person() {
    }

    public Person(Integer id, String name, String gender) {
        this.id = id;
        this.name = name;
        this.gender = gender;
    }

    public static void printInfo(){
        System.out.println("我是静态方法,反射把我给调用咯");
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

 

 

 

主要过程看注释,交流可评论在下方!