Java - 反射

文章目录

目录

文章目录

前言

一 . 什么是反射?

二 . 反射的使用

1.获取class对象

3.获取成员变量

4.获取成员方法

总结


前言

大家好,今天给大家介绍一下java中的反射,在学习web和框架的时候反射是不可或缺的,偏底层的内容会大量使用反射,很重要。


一 . 什么是反射?

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

Java的反射机制主要依赖于以下几个类:

  1. Class类:表示一个类或接口,在运行时可以通过该类获取该类的构造方法、字段、方法等信息。

  2. Constructor类:表示一个构造方法,可以通过该类创建对象。

  3. Field类:表示类的字段,可以通过该类访问和修改字段的值。

  4. Method类:表示类的方法,可以通过该类调用方法。

Java - 反射_第1张图片

 Java - 反射_第2张图片

二 . 反射的使用

1.获取class对象

Java - 反射_第3张图片

在Java中,可以通过以下几种方式来获取Class对象:

  1. 使用对象的getClass()方法:每个对象都有一个getClass()方法,可以通过该方法获取该对象所属的类的Class对象。
MyClass obj = new MyClass();
Class clazz = obj.getClass();
  1. 使用类名.class语法:通过类名后面加上".class"来获取该类的Class对象。
Class clazz = MyClass.class;
  1. 使用Class.forName()方法:通过类的全限定名(包名+类名)来获取该类的Class对象。需要注意的是,使用Class.forName()方法时需要提供类的全限定名,并且需要处理ClassNotFoundException异常。
Class clazz = Class.forName("com.example.MyClass");


 2.获取构造方法

1.Constructor[] getConstructors() 获取全部构造器(只能获取public修饰的)
​​​​​
2.Constructor[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到)

3.Constructor getConstructor(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}

3.获取成员变量

 

在Java中,Class类提供了多个用于获取成员变量的方法。以下是一些常用的方法:

  1. getField(String name):获取指定名称的公共成员变量(包括父类中的公共成员变量)。
  2. getDeclaredField(String name):获取指定名称的成员变量(不包括父类中的成员变量),无论其访问修饰符是什么。
  3. getFields():获取所有的公共成员变量(包括父类中的公共成员变量)。
  4. 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}

4.获取成员方法

java.lang.Class类中用于获取成员方法的方法:

  1. public Method getMethod(String name, Class... parameterTypes):根据方法名和参数类型获取指定的公共成员方法(包括继承的方法)。

  2. public Method[] getMethods():获取所有的公共成员方法(包括继承的方法)。

  3. public Method getDeclaredMethod(String name, Class... parameterTypes):根据方法名和参数类型获取指定的成员方法(不包括继承的方法)。

  4. public Method[] getDeclaredMethods():获取所有的成员方法(不包括继承的方法)。


 和上面都一样,不再多说,我们来看看 Method中的方法

  1. public Object invoke(Object obj, Object... args):通过反射调用该方法,传入指定对象和参数,并返回方法的返回值。

  2. public Class getReturnType():获取方法的返回类型,返回一个Class对象。

  3. public String getName():获取方法的名称。

  4. public int getModifiers():获取方法的修饰符,返回一个代表修饰符的整数。

  5. public Class[] getParameterTypes():获取方法的参数类型,返回一个Class对象数组。

  6. public void setAccessible(boolean flag):设置方法是否可访问。


 student类中加上该方法用来演示invoke方法Java - 反射_第4张图片Java - 反射_第5张图片


总结

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

你可能感兴趣的:(java从入门到起飞,java)