反射(基本)

关于反射的理解

反射(Reflection) 是程序在运行时动态获取类型信息(类、接口、方法、属性等)并操作其结构或行为的能力。通过反射,可以在不提前知道类具体定义的情况下,动态创建对象、调用方法、访问字段等。其核心原理是通过类的元数据(metadata)实现动态操作。


问题 1:是否可以通过反射获取接口的实例化对象?为什么?

答案:
不能直接通过反射实例化接口,因为接口本身没有具体的实现代码,无法直接创建实例。
但可以通过以下两种方式间接实现类似效果:

  1. 动态代理(Dynamic Proxy):例如 Java 中的 Proxy.newProxyInstance(),可以生成一个实现了接口的代理对象。

  2. 通过具体实现类:反射可以实例化接口的具体实现类,并通过接口引用操作对象。

原因:接口是抽象定义,必须依赖具体实现类的代码才能运行。


问题 2:是否可以通过反射获取抽象类的实例化对象?为什么?

答案:
不能直接通过反射实例化抽象类,因为抽象类可能包含未实现的抽象方法。
但有两种特殊情况:

  1. 抽象类没有抽象方法:若抽象类所有方法均已实现,理论上可以通过反射实例化,但 Java 等语言仍会阻止(抛出 InstantiationException)。

  2. 子类化抽象类:反射可以实例化抽象类的具体子类。

原因:抽象类本质是未完全实现的类,必须由子类补全逻辑后才能实例化。


反射的典型应用场景

  1. 框架设计:如 Spring 通过反射实现依赖注入(@Autowired)。

  2. 序列化/反序列化:JSON 库(如 Jackson)通过反射解析对象字段。

  3. 动态代理:AOP 编程中生成代理对象。

  4. IDE 智能提示:通过反射获取类的成员信息。

  5. 插件系统:动态加载外部类并调用其方法。


new 和反射创建对象的区别

特性new 关键字反射
编译时/运行时编译时确定类型,直接生成对象运行时动态解析类信息,间接生成对象
性能高效(JVM 直接优化)较慢(需解析元数据,安全检查)
灵活性仅能创建已知具体类可动态加载未知类(如从配置文件读取类名)
访问权限受构造方法权限控制(如私有构造无法调用)可绕过权限限制(通过 setAccessible(true)
代码耦合度高(需显式依赖具体类)低(通过类名字符串解耦)

总结

  1. 接口和抽象类:反射无法直接实例化,必须依赖具体实现类或动态代理。

  2. 反射核心价值:通过动态性和灵活性支持框架、工具等高级功能。

  3. 性能权衡:反射牺牲了性能,但扩展了运行时能力

反射创建对象的 3 种方式

以下以创建一个 String 对象为例(假设类名为 com.example.MyClass):

1. 通过 Class.forName() + 构造方法
// 1. 获取 Class 对象
Class<?> clazz = Class.forName("java.lang.String");

// 2. 获取无参构造方法(若需要参数,需指定参数类型)
Constructor<?> constructor = clazz.getDeclaredConstructor();

// 3. 如果是私有构造方法,需允许访问
constructor.setAccessible(true);

// 4. 调用构造方法创建实例
String str = (String) constructor.newInstance();
2. 通过 类名.class + 有参构造方法
// 直接通过类名获取 Class 对象
Class<String> clazz = String.class;

// 获取有参构造方法(如 String 的 byte[] 构造)
Constructor<String> constructor = clazz.getDeclaredConstructor(byte[].class);

// 创建实例并传入参数
byte[] bytes = {72, 101, 108, 108, 111};
String str = constructor.newInstance(bytes);  // 输出 "Hello"
3. 通过 对象.getClass()(适用于已有实例)
String existingStr = "Hello";
Class<?> clazz = existingStr.getClass();

// 后续步骤与方式 1 相同
Constructor<?> constructor = clazz.getDeclaredConstructor();
String newStr = (String) constructor.newInstance();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值