反射Reflection

1.1 简介

反射是框架设计的灵魂

将类的各个组成部分封装为其他对象

Source源代码阶段->Class类对象阶段->Runtime运行时阶段

1.2 获取Class对象

  1. Class.forName()
  2. 类名.class
  3. 对象.getClass()
public class Test01 {
    /*
    获取Class对象的三种方式:
     */
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Class.forName:将字节码文件加载进内存,返回Class对象。多用于配置文件。
        Class aClass = Class.forName("com.xxx.night.User");
        //2.类名.class:通过类名的属性class来获取。多用于参数的传递。
        Class aClass1 = User.class;
        //3.对象.getClass:在Object类中定义。多用于对象的获取字节码的方式。
        User user = new User();
        Class aClass2 = user.getClass();

        System.out.println(aClass == aClass1);//true
        System.out.println(aClass == aClass2);//true
    }
}

1.3 Class对象的获取功能

1.3.1 获取成员变量
  • Field[] getFields()
  • Field getField(String name)
  • Field[] getDeclaredFields()
  • Field getDeclaredField(String name)
import java.lang.reflect.Field;

public class Test02 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        //1、Field[] getFields()获取所有public修饰的成员变量
        Class userClass = User.class;
        Field[] fields = userClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //2、Field getField(String name)获取指定名字的public修饰的成员变量
        Field field = userClass.getField("name");

        User user = new User();//获取成员变量name的值
        field.get(user);
        
        field.set(user,"张三");//设置name的值
        System.out.println(user);

        //3、Field[] getDeclaredFields()获取所有成员变量,不考虑修饰符
        Field[] declaredFields = userClass.getDeclaredFields();
        for (Field df : declaredFields) {
            System.out.println(df);
        }

        //4、Field getDeclaredField(String name)
        Field declaredField = userClass.getDeclaredField("age");
        declaredField.setAccessible(true);//暴力反射
        Object o = declaredField.get(user);
        System.out.println(o);

    }
}

1.3.2 获取构造方法
  • Constructor<?>[] getConstructors()
  • Constructor getConstructor(类<?>... parameterTypes )
  • Constructor getDeclaredConstructor(类<?>... parameterTypes )
  • Constructor<?>[] getDeclaredConstructors()
	/*
    1、getConstructors()获取所有public修饰的构造方法
     */
    @Test
    public void show1() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> c : constructors) {
            System.out.println(c);
        }
    }

	/*
    2、getDeclaredConstructors()获取所有的构造方法,包括私有
    */
    @Test
    public void show2() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");

        Constructor<?>[] dcs = aClass.getDeclaredConstructors();
        for (Constructor<?> dc : dcs) {
            System.out.println(dc);
        }
    }

	/*
    3、getConstructor()获取单个public修饰的构造方法
     */
    @Test
    public void show3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class aClass = Class.forName("com.xxx.forenoon.User");

        Constructor con = aClass.getConstructor();

        User in = (User) con.newInstance();
        in.getName();

    }

	/*
    4、getDeclaredConstructor()获取单个私有构造方法
     */
    @Test
    public void show4() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取class对象
        Class aClass = Class.forName("com.xxx.forenoon.User");

        //获取单个私有构造方法
        Constructor constructor = aClass.getDeclaredConstructor(String.class, int.class);

        //使用暴力反射取出私有
        constructor.setAccessible(true);

        User user = (User) constructor.newInstance("小明", 18);
        System.out.println(user.name);

    }

1.3.3 获取成员方法
  • Method[] getMethods()
  • Method getMethod(String name,类<?>... parameterTypes)
  • Method[] getDeclaredMethods()
  • Method getDeclaredMethod(String name,类<?>... parameterTypes )
	/*
    1、Method[] getMethods()获取所有public修饰的成员方法
     */
    @Test
    public void showInfo() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");
        //获取所有公有成员方法
        Method[] methods = aClass.getMethods();
        for (Method m : methods) {
            System.out.println(m);
        }
    }

    /*
    2、getDeclaredMethods()获取所有成员方法,包括私有
     */
    @Test
    public void showInfo2() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");
        Method[] methods = aClass.getDeclaredMethods();
        for (Method m : methods) {
            System.out.println(m);
        }
    }

    /*
    3、getConstructor()获取单个public修饰的成员方法
     */
    @Test
    public void showInfo3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");
        //先获取构造方法
        Constructor<?> constructor = aClass.getConstructor();
        //再实例化对象
        Object o = constructor.newInstance();

        //获取单个公有的成员方法
        //getMethod的参数是(方法名)
        Method showInfo = aClass.getMethod("showInfo");
        //invoke的参数是(实例化对象)
        showInfo.invoke(o);
    }

    /*
    4、getConstructor()获取单个私有成员方法
     */
    @Test
    public void showInfo4() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");
        //先获取构造方法
        Constructor<?> constructor = aClass.getConstructor();
        //再实例化对象
        Object o = constructor.newInstance();

        //获取单个私有成员方法
        //getDeclaredMethod的参数是(方法名,方法参数类型.class)
        Method show = aClass.getDeclaredMethod("show", String.class);
        //invoke的参数是(实例化对象,方法参数的实参)
        show.invoke(o,"包子");
    }
1.3.4 获取类名
  • String getName()
    @Test
    public void showInfo() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.xxx.forenoon.User");

        //获取类名
        String className = aClass.getName();
        System.out.println(className);

        //获取方法名
//        method.getName();
    }
posted @ 2022-10-27 20:59  Rix里克斯  阅读(30)  评论(0)    收藏  举报