反射的使用学习

如何获取类的结构信息:

//1 获取class对象
Class c = Class.forName("com.oop.demo07.Student");

//2 获取成员属性
Field[] fields = c.getFields(); //获取全部非私有成员属性,返回Field数组
Field[] fields = getDeclaredFields(); //获取全部成员属性(包括私有),返回Field数组
Field field = getField(指定属性名); //获取指定属性,返回Field(不返回私有属性)
Field field = getDeclaredField(指定属性名);  //获取指定属性的值 ,返回Field

//3.获取成员方法 (获取全部方法,同理参考成员属性)
Method[] methods = c.getMethods();
Method[] methods = c.getDeclaredMethods();
Method  method= c.getMethod(方法名,参数类型.class);
Method  method= c.getDeclaredMethod(方法名,参数类型.class);

//4.获取构造器
Constructor[] constructors = c.getConstructors;//获取全部非私有构造器,参考上面
Constructor[] constructors = c.getDeclaredConstructors();//获取全部构造器,参考上面
Constructor constructor = c.getConstructor(参数类型.class);
Constructor constructor = c.getDeclaredConstructor(参数类型.class);

//为什么要获取方法和构造器需要加入参数
//原因:因为方法和构造器都可能会出现方法重载,所以必须要加入参数类型,才能准确获取目标方法、构造器

动态创建对象执行方法:

  1. 创建对象:

    • 无参构造 : newInstance()方法
    • 有参构造:不能直接用Class对象的 newInstance()方法,要先获取指定构造器对象,再传参构造
  2. 调用方法:

    • 通过class对象获取Method方法对象(见上)
    • 激活:invoke(Object o , 参数)方法执行必须用invoke激活,传入对象,参数
    • 调用私有方法,必须开启权限setAccessible(true)方法
  3. 调用属性:

    • 通过class对象获取Field对象(见上)
    • 调用Field对象的set(Object o , 参数)方法设置属性,传入对象,参数
    • 修改私有属性,必须开启权限setAccessible(true)方法

参考代码

package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
public class Demo08 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c = Class.forName("com.reflection.User");
        //无参构造
        User user1 = (User) c.newInstance();//1.父类转子类(高转低)必须要加(类型)强转  2. 本质调用无参构造器
        System.out.println(user1);

        //有参构造,不能直接用Class,要先获取指定构造器对象,再传参构造
        Constructor Constructor = c.getDeclaredConstructor(String.class, int.class, int.class);
        User user2 = (User) Constructor.newInstance("AAA", 001,18);
        System.out.println(user2);

        //通过反射调用方法
        User user3 = (User) c.newInstance();
        Method setName = c.getMethod("setName", String.class);
        setName.invoke(user2,"user2");
        setName.invoke(user3,"user3");
        System.out.println(user1.getName());
        System.out.println(user2.getName());
        System.out.println(user3.getName());

        //通过反射操作属性,不能直接操作私有属性,需要赋予访问权限(安全检查)
        User user4 = (User) c.newInstance();
        Field name = c.getDeclaredField("name");
        name.setAccessible(true);//如果是私有属性,需要设置访问权限
        name.set(user4,"user4-test");
        System.out.println(user4.getName());

    }
}
class User{
    private String name ;
    private int id;
    private int age;

    public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }

    public User() {
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id == user.id && age == user.age && Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, id, age);
    }
}

posted @ 2021-07-27 00:12  没离开过o  阅读(28)  评论(0)    收藏  举报