编程自学指南:java程序设计开发,反射机制动态创建对象,反射的核心作用,反射创建对象的三大核心步骤,反射的本质,获取 Class 对象的三种方式

Java 反射机制动态创建对象详解课件(初学者版)

一、课程信息

学习目标

  1. 理解反射的核心作用:动态操作类的信息
  2. 掌握反射创建对象的三大核心步骤
  3. 能通过反射突破构造器权限,实现灵活创建
  4. 理解反射的优缺点及适用场景,避免滥用

二、课程导入:生活中的 "动态"

🌰 场景类比:万能工厂

  • 传统工厂:提前知道产品类型,用new创建(如new Car()
  • 反射工厂:根据 "图纸名称" 动态生产(如根据配置文件中的类名创建对象)

三、反射基础:Class 对象

1. 反射的本质

在运行时获取类的信息,并动态创建对象、调用方法
核心:通过Class对象获取类的元数据

2. 获取 Class 对象的三种方式

方式 1:Class.forName("全类名")(最常用)
Class<?> clazz = Class.forName("com.example.Student");
方式 2:类名.class(编译时已知类)
Class<Student> clazz = Student.class;
方式 3:对象.getClass()(运行时获取对象类型)
Student stu = new Student();
Class<?> clazz = stu.getClass();

3. 案例:打印类信息

class Student {
    private String name;
    public Student(String name) { this.name = name; }
}

public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 方式1
        Class<?> clazz1 = Class.forName("Student"); // 需导入包或全类名
        // 方式2
        Class<Student> clazz2 = Student.class;
        // 方式3
        Student stu = new Student("张三");
        Class<?> clazz3 = stu.getClass();
        
        System.out.println("类名:" + clazz1.getName()); // Student
        System.out.println("是否为接口:" + clazz1.isInterface()); // false
    }
}

四、反射创建对象的核心步骤

🔧 步骤 1:获取构造器

获取无参构造器
Constructor<?> constructor = clazz.getConstructor();
获取有参构造器
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
获取私有构造器(需暴力反射)
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
constructor.setAccessible(true); // 忽略权限检查

🔧 步骤 2:创建对象

无参构造器创建
Object obj = constructor.newInstance();
有参构造器创建
Object obj = constructor.newInstance("张三", 18);

🔍 完整案例:动态创建学生对象

class Student {
    private String name;
    private int age;

    // 无参构造器(默认public)
    public Student() {}

    // 私有有参构造器
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class ReflectionCreateObject {
    public static void main(String[] args) throws Exception {
        Class<Student> clazz = Student.class;

        // 方式1:调用无参构造器
        Student stu1 = clazz.newInstance(); // JDK9+已过时,改用构造器

        // 方式2:通过构造器创建(推荐)
        Constructor<Student> publicConstructor = clazz.getConstructor();
        Student stu2 = publicConstructor.newInstance();

        // 方式3:调用私有构造器
        Constructor<Student> privateConstructor = clazz.getDeclaredConstructor(String.class, int.class);
        privateConstructor.setAccessible(true); // 暴力访问
        Student stu3 = privateConstructor.newInstance("李四", 20);
    }
}

五、反射 vs new关键字

特性反射new关键字
创建时机运行时动态决定编译时确定
构造器权限可突破私有构造器只能调用 public 构造器
灵活性高(根据类名字符串创建)低(需硬编码类名)
性能低(涉及额外校验)

六、实际应用案例

🔥 案例 1:根据配置文件创建对象(模拟框架)

场景:从config.properties读取类名,动态创建日志处理器

# config.properties
logger.class=com.example.FileLogger

代码实现

import java.io.FileInputStream;
import java.util.Properties;

interface Logger {
    void log(String msg);
}

class FileLogger implements Logger {
    public void log(String msg) {
        System.out.println("文件日志:" + msg);
    }
}

public class ReflectionConfig {
    public static void main(String[] args) throws Exception {
        // 读取配置文件
        Properties props = new Properties();
        props.load(new FileInputStream("config.properties"));
        String className = props.getProperty("logger.class");

        // 反射创建对象
        Class<?> clazz = Class.forName(className);
        Logger logger = (Logger) clazz.newInstance();
        logger.log("反射创建对象成功");
    }
}

🔥 案例 2:通用对象复制工具

需求:将一个对象的属性值复制到另一个同类型对象

public static void copy(Object source, Object target) throws Exception {
    Class<?> clazz = source.getClass();
    // 获取所有public字段
    Field[] fields = clazz.getFields();
    for (Field field : fields) {
        Object value = field.get(source);
        field.set(target, value);
    }
}

// 使用
Student stu1 = new Student("张三", 18);
Student stu2 = new Student();
copy(stu1, stu2); // stu2的属性被复制

七、初学者必避的 3 大陷阱

陷阱 1:类名错误导致ClassNotFoundException

Class.forName("com.example.UnknownClass"); // 类不存在时抛异常

陷阱 2:构造器参数类型不匹配

clazz.getConstructor(int.class); // 实际构造器是(String.class)

陷阱 3:忽略权限检查

Constructor<?> constructor = clazz.getDeclaredConstructor();
// 未调用setAccessible(true)直接调用newInstance()
// 私有构造器会抛IllegalAccessException

八、课堂练习

练习 1:反射创建私有构造器对象

任务:为Singleton类(私有构造器)实现反射创建,绕过单例限制

练习 2:动态调用方法

需求:通过反射调用String类的toUpperCase()方法

九、课程总结

知识图谱:

反射创建对象  
   ↳ 核心步骤:获取Class→获取构造器→newInstance()  
   ↳ 暴力反射:setAccessible(true)突破权限  
   ↳ 应用场景:框架开发、插件系统、通用工具  

口诀记忆:

“反射反射真神奇,运行时刻探类密,
Class 对象是钥匙,构造方法来创建,
私有权限也能破,框架开发离不了!”

十、课后作业

必做 1:反射实现工厂模式

需求:用反射优化工厂模式,根据类名字符串创建对象

必做 2:分析 Spring 的 Bean 创建

任务:查阅 Spring 源码,说明BeanFactory如何用反射创建 Bean

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zl515035644

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值