Java成神路 —— 反射

2023-05-07 17:09:07 浏览数 (1)

1. 反射的概述

  • 反射是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。
  • 由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

2. 获取Class类对象的三种方式

2.1 三种方式

  • 类名.class属性
  • 对象名.getClass()方法
  • Class.forName(全类名)方法

2.2 示例代码

代码语言:javascript复制
class People {

}

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException{

        // 使用类的class属性来获取该类对应的class对象
        Class<People> p1 = People.class;
        System.out.println(p1);

        Class<People> p2 = People.class;
        System.out.println(p1 == p2);

        // 调用对象的getClass()方法,返回该对象所属类对应的class对象
        People p3 = new People();
        Class<? extends People> p4 = p3.getClass();
        System.out.println(p1 == p4);

        // 使用class类中的静态方法forName(String className)
        Class<?> p5 = Class.forName("People");
        System.out.println(p1 == p5);
    }
}

3. 反射获取构造方法并使用

3.1 Class类获取构造方法对象的方法

1. 方法分类

方法名

说明

Constructor <?>[] getConstructors()

返回所有公共构造方法对象的数组

Constructor <?>[] getDeclaredConstructors()

返回所有构造方法对象的数组

Constructor getConstructor(Class <?>… parameterTypes)

返回单个公共构造方法对象

Constructor getDeclaredConstructor(Class <?>… parameterTypes)

返回单个构造方法对象

2. 示例代码
代码语言:javascript复制
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class People {
    public People(){
        
    }
}
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodError, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {

        // 获取Class对象
        Class<?> c = Class.forName("People");

        // Constructor<?>[] getConstructors() 返回一个包含 Constructor对象的数组,Constructor对象反映了由该 class对象表示的类的所有公共构造函数
        // Constructor<?>[] cons = c.getConstructors();

        // Construct<?> getDeclaredConstructs() 返回反映由该class 对象表示类声明的所有的构造函数的 Constructor对象的数组
        Constructor<?>[] cons = c.getDeclaredConstructors();

        for(Constructor con : cons) {
            System.out.println(con);
        }

        //---------------

        // Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor对象,该对象由该 Class对象表示的类的指定公共构造函数
        // Constructor<T> getDeclaredConstructod(Class<?>... parameterTypes) 返回一个 Constructor对象,该对象反应由此 Class对象表示的类或接口的指定构造函数
        // 参数:要获取的构造方法的参数的个数和数据类型对象的字节码文件对象

        Constructor<?> con = c.getConstructor();

        // constructor 提供了一个类的单个构造函数的信息和访问权限
        // T newInstance(Object... initargs) 使用由此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例

        Object obj = con.newInstance();
        System.out.println(obj);

    }
}

3.2 Constructor类用于创建对象的方法

方法名

说明

T newInstance(Object…initargs)

根据指定的构造方法创建对象

4. 反射获取成员变量并使用

4.1 Class类获取成员变量对象的方法

1. 方法分类

方法名

说明

Field[] getFields()

返回所有公共成员变量对象的数组

Field[] getDeclaredFields()

返回所有成员变量对象的数组

Field getField(String name)

返回单个公共成员变量对象

Field getDeclaredField(String name)

返回单个成员变量对象

2. 示例代码
代码语言:javascript复制
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

class People{
    public People() {

    }
    public String address;
}

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchFieldException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {

        //获取Class对象
        Class<?> c = Class.forName("People");

        // Field[] getFields() 返回一个包含 Field对象的数组, Field对象反映由该 Class对象表示的类或接口的所有可访问的公共字段
        // Field[] getDeclaredFields() 返回一个 Field对象的数组,反映了由该 Class对象表示的类或接口声明的所有字段
        // Field[] fields = c.getFields();
        Field[] fields = c.getDeclaredFields();

        for(Field field : fields) {
            System.out.println(field);
        }

        //Field getField(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定公共成员字段
        //Field getDeclaredField(String name) 返回一个 Field对象,该对象反映由该Class对象表示的类或接口的指定声明字段
        Field addressField = c.getField("address");

        //获取无参构造方法创建对象
        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        // obj.addressField = "安徽";
        //Field提供有关类或接口的单个字段的信息和动态访问
        //void set(Object obj, Object value) 将指定的对象参数中由此 Field对象表示的字段设置为指定的新值
        addressField.set(obj,"安徽"); //给obj的成员变量addressField赋值为安徽
        System.out.println(obj);

    }
}

4.2 Field类用于给成员变量赋值的方法

方法名

说明

voidset(Object obj,Object value)

给obj对象的成员变量赋值为value

5. 反射获取成员方法并使用

5.1 Class类获取成员方法对象的方法

1. 方法分类

方法名

说明

Method[] getMethods()

返回所有公共成员方法对象的数组,包括继承的

Method[] getDeclaredMethods()

返回所有成员方法对象的数组,不包括继承的

Method getMethod(String name, Class<?>… parameterTypes)

返回单个公共成员方法对象

Method getDeclaredMethod(String name, Class<?>… parameterTypes)

返回单个成员方法对象

5.2 Method类用于执行方法的方法

方法名

说明

Objectinvoke(Object obj,Object… args)

调用obj对象的成员方法,参数是args,返回值是Object类型

0 人点赞