大家好,今天给大家介绍一下java中的反射,在学习web和框架的时候反射是不可或缺的,偏底层的内容会大量使用反射,很重要。
Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Java的反射机制主要依赖于以下几个类:
Class类:表示一个类或接口,在运行时可以通过该类获取该类的构造方法、字段、方法等信息。
Constructor类:表示一个构造方法,可以通过该类创建对象。
Field类:表示类的字段,可以通过该类访问和修改字段的值。
Method类:表示类的方法,可以通过该类调用方法。



在Java中,可以通过以下几种方式来获取Class对象:
- MyClass obj = new MyClass();
- Class extends MyClass> clazz = obj.getClass();
Class<MyClass> clazz = MyClass.class;
Class<?> clazz = Class.forName("com.example.MyClass");
2.获取构造方法

1.Constructor>[] getConstructors() 获取全部构造器(只能获取public修饰的) 2.Constructor>[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到) 3.ConstructorgetConstructor(class>... parameterTypes) 获取某个构造器(只能获取public修饰的) 4.Constructor getDeclaredConstructor(Class>... parameterTypes) 获取某个构造器(只要存在就能拿到,不管是不是private修饰的)
- import java.lang.reflect.Constructor;
-
- public class MyClass {
- public MyClass() {
- }
-
- public MyClass(int value) {
- }
-
- public static void main(String[] args) {
- try {
- // 获取公共的无参构造方法
- Constructor> constructor1 = MyClass.class.getConstructor();
- System.out.println(constructor1);
-
- // 获取公共的有参构造方法
- Constructor> constructor2 = MyClass.class.getConstructor(int.class);
- System.out.println(constructor2);
-
- // 获取所有的构造方法
- Constructor>[] constructors = MyClass.class.getDeclaredConstructors();
- for (Constructor> constructor : constructors) {
- System.out.println(constructor);
- }
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- }
- }
- }
输出结果为:
- public com.example.MyClass()
- public com.example.MyClass(int)
- private com.example.MyClass()
Constructor类中常用的方法:
T newInstance(Object....args) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 public void setAccessible(Boolean flag) 设置为true,表示禁止检查访问控制(暴力反射,临时取消权限校验)
student类:
- public class Student {
- private String name;
- private int age;
-
- public Student() {
- }
-
- private Student(String name, int age) {
- this.name = name;
- this.age = age;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Student{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
- import java.lang.reflect.Constructor;
-
- public class ReflectionExample {
- public static void main(String[] args) {
- try {
- // 获取有参构造方法
- Constructor
constructor = Student.class.getDeclaredConstructor(String.class, int.class); -
- // 设置为可访问 暴力反射 临时取消访问检测
- constructor.setAccessible(true);
-
- // 调用构造方法创建实例
- Student student = constructor.newInstance("John", 20);
- System.out.println(student);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
输出
Student{name='John', age=20}

在Java中,Class类提供了多个用于获取成员变量的方法。以下是一些常用的方法:
getField(String name):获取指定名称的公共成员变量(包括父类中的公共成员变量)。getDeclaredField(String name):获取指定名称的成员变量(不包括父类中的成员变量),无论其访问修饰符是什么。getFields():获取所有的公共成员变量(包括父类中的公共成员变量)。getDeclaredFields():获取所有的成员变量(不包括父类中的成员变量),无论其访问修饰符是什么。- import java.lang.reflect.Field;
-
- public class MyClass {
- public static void main(String[] args) {
- try {
- // 获取指定名称的公共成员变量
- Field field1 = Student.class.getField("name");
- System.out.println(field1);
-
- // 获取指定名称的成员变量
- Field field2 = Student.class.getDeclaredField("age");
- System.out.println(field2);
-
- // 获取所有的公共成员变量
- Field[] fields1 = Student.class.getFields();
- for (Field field : fields1) {
- System.out.println(field);
- }
-
- // 获取所有的成员变量
- Field[] fields2 = Student.class.getDeclaredFields();
- for (Field field : fields2) {
- System.out.println(field);
- }
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- }
- }
- }
Field类中常用的方法
1.void set(Object obj,Object value) 为obj对象里的成员变量赋值为value
2.Object get(Object obj) 取出obj对象中的值
3.public void setAccessible(Boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
-
- public class ReflectionExample {
- public static void main(String[] args) {
- try {
- // 使用反射调用构造方法创建实例
- Constructor
constructor = Student.class.getDeclaredConstructor(String.class, int.class); - constructor.setAccessible(true);
- Student student = constructor.newInstance("John", 20);
- System.out.println(student);
-
- // 使用反射获取和修改成员变量的值
- Field nameField = Student.class.getDeclaredField("name");
- nameField.setAccessible(true);
- nameField.set(student, "Tom");
-
- Field ageField = Student.class.getDeclaredField("age");
- ageField.setAccessible(true);
- int age = (int) ageField.get(student);
- ageField.set(student, age + 1);
-
- System.out.println(student);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
输出结果为:
- Student{name='John', age=20}
- Student{name='Tom', age=21}

java.lang.Class类中用于获取成员方法的方法:
public Method getMethod(String name, Class>... parameterTypes):根据方法名和参数类型获取指定的公共成员方法(包括继承的方法)。
public Method[] getMethods():获取所有的公共成员方法(包括继承的方法)。
public Method getDeclaredMethod(String name, Class>... parameterTypes):根据方法名和参数类型获取指定的成员方法(不包括继承的方法)。
public Method[] getDeclaredMethods():获取所有的成员方法(不包括继承的方法)。
和上面都一样,不再多说,我们来看看 Method中的方法
public Object invoke(Object obj, Object... args):通过反射调用该方法,传入指定对象和参数,并返回方法的返回值。
public Class> getReturnType():获取方法的返回类型,返回一个Class对象。
public String getName():获取方法的名称。
public int getModifiers():获取方法的修饰符,返回一个代表修饰符的整数。
public Class>[] getParameterTypes():获取方法的参数类型,返回一个Class对象数组。
public void setAccessible(boolean flag):设置方法是否可访问。
student类中加上该方法用来演示invoke方法

今天的内容就到这了,大家好好理解。