# 定义

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

其实在 Java 中定义的一个类本身也是一个对象,即 java.lang.Class 类的实例,这个实例称为类对象

  • 类对象表示正在运行的 Java 应用程序中的类和接口
  • 类对象没有公共构造方法,由 Java 虚拟机自动构造
  • 类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法

要得到类的方法和属性,首先就要得到该类对象

# 获取类对象

假设现在有一个 Person 类

public class Person {
    public String name;
    private int age;
    public Person(){
        System.out.println("无参构造方法");
    }
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    public void action(String string){
        System.out.println(string);
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

要获取该类对象一般有三种方法

  • Class.forName("reflection.User")

  • User.class

  • new User().getClass()

    最常用的是第一种,通过一个字符串即类的全路径名就可以得到类对象,另外两种方法依赖项太强

我们看一下 Class.forName

image-20220413105214970

意思是传递一个类名返回其 Class 泛型

# 利用类对象创建对象

# 调用无参构造方法创建对象

当调用无参构造方法的时候,直接 newInstance 即可

public class Reflectiontest {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("Person");
        c.newInstance();
    }
}

image-20220413105820434

# 调用有参构造函数创建对象

这里需要先获取类里面的构造方法

常用方法介绍

方法说明
getConstructor(Class...<?> parameterTypes)获得该类中与参数类型匹配的公有构造方法
getConstructors()获得该类的所有公有构造方法
getDeclaredConstructor(Class...<?> parameterTypes)获得该类中与参数类型匹配的构造方法
getDeclaredConstructors()获得该类所有构造方法
import java.lang.reflect.Constructor;
public class Reflectiontest {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("Person");
        Constructor constructor = c.getConstructor(String.class, int.class);
        Person person = (Person) constructor.newInstance("miku", 18);
        System.out.println(person.name);
    }
}

image-20220413110957088

# 通过反射调用方法

方法说明
getMethod(String name, Class...<?> parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Reflectiontest {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("Person");
        Constructor constructor = c.getDeclaredConstructor(String.class, int.class);
        Person a = (Person) constructor.newInstance("aaa", 1);
        Method action = c.getDeclaredMethod("action", String.class);
        action.invoke(a,"action method");
    }
}

image-20220413112736324

# 通过反射访问属性

方法说明
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象
getDeclaredField(String name)获得某个属性对
getDeclaredFields()获得所有属性对象
Field field = c.getDeclaredField("name");

获取对象属性后可以给实例赋值

例如有一个 Person 实例 a, 用反射将其中的 public 属性 name 修改

Field field = c.getDeclaredField("name");
        field.set(a, "miku");

如果要修改 private 属性,需要添加下面一句话

field.setAccessible(true);
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Reflectiontest {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("Person");
        Constructor constructor = c.getDeclaredConstructor(String.class, int.class);
        Person a = (Person) constructor.newInstance("aaa", 1);
        System.out.println(a);
        Field field = c.getDeclaredField("name");
        field.set(a, "miku");
        Field field1 = c.getDeclaredField("age");
        field1.setAccessible(true);
        field1.set(a, 18);
        System.out.println(a);
    }
}

image-20220413112035907

请我喝[茶]~( ̄▽ ̄)~*

miku233 微信支付

微信支付

miku233 支付宝

支付宝

miku233 贝宝

贝宝