Java 基础——反射机制

什么是反射

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

Class类

获取Class对象的方式:

  1. 调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如:
    MyObject x;
    Class c1 = x.getClass();

  2. 使用Class类的中静态forName()方法获得与字符串对应的Class对象。例如:
    Class c2=Class.forName(“类名或接口名”);

  3. 如果T是一个Java类型,那么T.class就代表了匹配的类对象。例如:
    Class cl1 = Manager.class;
    Class cl2 = int.class;
    Class cl3 = Double[].class;

  4. 通过类加载器获取类对象,例如:
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Class cl1 = loader.loadClass("类名");

Class类的重要方法如下:

  1. 获取类名
    • String getName()
  2. 获取Class对象
    • static Class<?> forName(String className)
  3. 获取类加载器
    • ClassLoader getClassLoader()
  4. 创建类的实例
    • T newInstance()
  5. 获取反射类对象
    1. 获取构造函数反射类
      • Constructor getConstructor(Class<?>... parameterTypes)
      • Constructor<?>[] getConstructors()
      • Constructor getDeclaredConstructor(Class<?>... parameterTypes)
      • Constructor<?>[] getDeclaredConstructors()
    2. 获取类方法的反射类
      • Method getMethod(String name, Class<?>... parameterTypes)
      • Method[] getMethods()
      • Method getDeclaredMethod(String name, Class<?>... parameterTypes)
      • Method[] getDeclaredMethods()
    3. 获取类成员变量的反射类
      • Field getField(String name)
      • Field[] getFields()
      • Field getDeclaredField(String name)
      • Field[] getDeclaredFields()
  • 注意:getXXX()和getDeclaredXXX()的区别是,getXXX()只能获取public的反射类对象,getDeclaredXXX()则没有限制。

反射类

反射类通过Class类对象来获取,主要包括构造函数、成员变量、类方法,通过反射类对象可以实例化目标类、调用目标类对象的方法、操作目标类对象的域。

  1. java.lang.reflect.Constructor
    使用newInstance()方法实例化目标类,注意Class类的newInstance()方法只能调用默认无参构造函数,使用Constructor的newInstance()方法可以带参。
    • T newInstance(Object... initargs)
  2. java.lang.reflect.Method
    Method对象最重要的方法就是invoke(),相当于调用实例的方法:
    • Object invoke(Object obj, Object... args)
  3. java.lang.reflect.Field
    Field方法最主要的方法是set():
    • void set(Object obj, Object value)
    • void setXXX(Object obj, XXX z)

一个例子

https://github.com/kaname233/SpringLearn/tree/master/src/top/sunjing98/reflect
一个普通的Java类Student:

展开查看 ```java package top.sunjing98.reflect; public class Student { private String stuName; private int stuAge;
public Student() {
}

public Student(String stuName, int stuAge) {
    this.stuName = stuName;
    this.stuAge = stuAge;
}

public void introduce() {
    System.out.println("stuName: " + stuName + " stuAge: " + stuAge);
}

public String getStuName() {
    return stuName;
}

public void setStuName(String stuName) {
    this.stuName = stuName;
}

public int getStuAge() {
    return stuAge;
}

public void setStuAge(int stuAge) {
    this.stuAge = stuAge;
}

}

</details>
通过反射机制创建并操作目标类对象:
```java
package top.sunjing98.reflect;

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

public class ReflectTest {
    public static Student initByDefaultConst() throws Throwable {
        //1、通过类装载器获取类对象
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz = loader.loadClass("top.sunjing98.reflect.Student");
        //2、通过类对象获取构造器对象,通过构造器对象实例化类
        Constructor constructor = clazz.getDeclaredConstructor( null);
        Student s = (Student) constructor.newInstance();
        //3、通过类对象获取方法对象,通过反射方法设置属性
        Method setStuName = clazz.getMethod("setStuName", String.class);
        Method setStuAge = clazz.getMethod("setStuAge", int.class);
        setStuName.invoke(s, "张三");
        setStuAge.invoke(s, 23);
        return s;
    }

    public static void main(String[] args) throws Throwable {
        Student s = initByDefaultConst();
        s.introduce();
    }
}

输出:

stuName: 张三 stuAge: 23