认识-反射

反射

1.什么是反射

反射(Reflection)是一种 Java 程序运行期间动态技术,可以在运行时(runtime)检査、修改其自身结构或行为。通过反射,程序可以访问、检测和修改它自己的类、对象、方法、属性等成员

2.反射的定义

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

3.反射的用途

动态加载类:程序可以在运行时动态地加载类库中的类;
动态创建对象:反射可以基于类的信息,程序可以在运行时,动态创建对象实例;
调用方法:反射可以根据方法名称,程序可以在运行时,动态地调用对象的方法(即使方法在编写程序时还没有定义)
访问成员变量:反射可以根据成员变量名称,程序可以在运行时,访问和修改成员变量(反射可以访问私有成员变量)
运行时类型信息:反射允许程序在运行时,查询对象的类型信息,这对于编写通用的代码和库非常有用;

Spring 框架使用反射来自动装配组件,实现依赖注入;

MyBatis 框架使用反射来创建resultType 对象,封装数据查询结果

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Field类代表类的成员变量/类的属性
Method类代表类的方法
Constructor类代表类的构造方法
4.反射获取 Class 对象:
public class ReflectionExample {

    public static void main(String[] args) {
        try {
            // 获取 Class 对象
            Class<?> clazz = Class.forName("com.example.MyClass");

            // 使用反射创建对象
            Object obj = clazz.newInstance();

            // 输出对象信息
            System.out.println("对象创建成功: " + obj);
            
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

我们首先通过 Class.forName("com.example.MyClass") 获取 Class 对象,然后调用 newInstance() 创建对象。需要注意的是,newInstance() 方法在 Java 9 以后被标记为弃用,建议使用 ConstructornewInstance() 方法。

5.通过反射创建对象
try {
    Class<?> clazz = Class.forName("com.example.MyClass");
    Constructor<?> constructor = clazz.getConstructor(); // 获取无参构造函数
    Object obj = constructor.newInstance(); // 创建对象
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
    e.printStackTrace();
}
6.使用 Java 反射机制获取和调用类的构造方法,访问私有构造方法并创建对象

假设我们有一个类 MyClass,其中包含一个私有构造方法:

public class MyClass {
    private MyClass() {
        System.out.println("私有构造方法被调用");
    }

    public void display() {
        System.out.println("MyClass 实例方法");
    }
}

我们可以通过以下步骤来访问和调用这个私有构造方法:

import java.lang.reflect.Constructor;

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 获取 Class 对象
            Class<?> clazz = Class.forName("MyClass");

            // 获取私有构造方法
            Constructor<?> constructor = clazz.getDeclaredConstructor();

            // 设置构造方法可访问
            constructor.setAccessible(true);

            // 使用私有构造方法创建对象
            Object obj = constructor.newInstance();

            // 调用实例方法
            if (obj instanceof MyClass) {
                ((MyClass) obj).display();
            }

        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

  1. 获取 Class 对象:使用 Class.forName("MyClass") 或其他方法来获取 Class 对象。
  2. 获取构造方法:使用 getDeclaredConstructor() 获取指定的构造方法。由于是私有构造方法,我们需要使用 getDeclaredConstructor() 而不是 getConstructor()
  3. 设置可访问性:调用 setAccessible(true) 来绕过 Java 访问控制检查,使我们能够访问私有构造方法。
  4. 创建对象:使用 newInstance() 方法创建对象实例。
  5. 调用实例方法:如果需要,可以通过反射调用实例的方法。
7.通过反射,访问并使用成员方法

假设我们有一个类 MyClass,其中包含一些方法:

public class MyClass {
    private void privateMethod() {
        System.out.println("调用了私有方法");
    }

    public void publicMethod(String message) {
        System.out.println("调用了公共方法,消息: " + message);
    }
}

反射访问并使用成员方法

import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 获取 Class 对象
            Class<?> clazz = Class.forName("MyClass");
            
            // 创建 MyClass 实例
            Object obj = clazz.getDeclaredConstructor().newInstance();

            // 访问并调用私有方法
            Method privateMethod = clazz.getDeclaredMethod("privateMethod");
            privateMethod.setAccessible(true); // 设置方法可访问
            privateMethod.invoke(obj); // 调用方法

            // 访问并调用公共方法
            Method publicMethod = clazz.getMethod("publicMethod", String.class);
            publicMethod.invoke(obj, "Hello, Reflection!"); // 调用方法

        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

  1. 获取 Class 对象:通过 Class.forName("MyClass") 获取目标类的 Class 对象。

  2. 创建实例:使用 getDeclaredConstructor().newInstance() 创建类的实例。

  3. 访问私有方法

    • 使用 getDeclaredMethod("methodName") 获取私有方法对象。
    • 使用 setAccessible(true) 绕过 Java 访问控制检查。
    • 使用 invoke(obj) 调用方法。
  4. 访问公共方法

    • 使用 getMethod("methodName", parameterTypes) 获取公共方法对象。
    • 使用 invoke(obj, parameters) 调用方法,并传入所需参数。

这种方式允许你在运行时动态地调用方法,适用于需要灵活性和扩展性的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值