大约 3 分钟
反射 (Reflect)
各语言实现
反射库
- Java
- 有一个专门的包处理反射,配合注解使用
- python
- python作为脚本语言,根据类名字符生成类实例非常简单,类似java的Class.forName
- python是一个脚本语言,它不像java一样有一个专门的包来处理反射
- Python的内置函数提供了强大的反射机制
- C
- 自身不支持,也无特别好的库
- boost库有但似乎说不好用,另一个就是UE4的C++也有反射:这个视频有说大致原理:https://www.bilibili.com/video/BV1yv4y1m77s/
反射类
反射机制
- Java和C++一些相似的方法
- java的
newInstance方法
对应C++中虚拟构造器
的习惯用法。但有所不同- C++中的虚拟构造器不是一种语言特性,需要由专门的库支持
- java的
Class类
与C++中的type_info类
相似,java的getClass方法
与C++中的typeid
运算符等价- C++的type_info没Java的Class强大。只能以字符串的形式显示一个类型的名字,而不能创建那个类型的对象
- java的
- C++本身没有自带的反射机制。至于虚拟构造器和type_info我也没用过、不懂
反射枚举
C++的X宏可以实现编译期反射,也有一些像better_enum之类的反射枚举库
相关知识
概念
参考:反射-01-问题提出
问题:BlindBox 类中有1024个open开头方法,方法会返回从1~1024之间的整数且不会重复,问哪个方法会返回 666(不能查看源码)
答案:如果有一个方法,能知道这个类中所有的方法并遍历,这么就可以解决这个问题
public class Test1 {
public static void main(String[] args) throw InvocationTargetException, IllegalAccessExeption {
// ……
}
}
类的反射:反射即认清自己,让对象认清自己,知道对象的:
- 类名
- 父类
- 接口
- 成员变量
- 方法
并非所有语言具备认清对象自己的能力,如C++。你只能知道类有什么方法,再去调用他。但不能去获取类有什么方法,再去调用。
反射API
反射机制允许程序在运行时借助 Reflection API 取得任何类的内部信息,并能直接操作对象的内部属性和方法(比如用字符串索引函数地址或类成员偏移地址)
原理
Java的反射枚举,原理大概是:把下面这些信息都给它记录下来,并且呢在类加载的时候把这些信息收集起来,放在一个特殊的对象中 —— InstanceKlass
- 类名
- 父类
- 接口
- 成员变量
- 成员方法
- 虚方法
__java__mirror
,通过这个类方法,可以获取上面的信息
分类
- 根据作用时期
- 编译期反射。例如:C的X宏,可以类似这样的效果:在编译期间查枚举表
- 运行期反射。例如:真正靠字符串进行反射的java、python的反射
- 根据作用点
- 类反射
- 类对象反射
- 类成员数据反射
- 类成员函数反射
- 枚举反射
- 类反射
和序列化、反序列化的联系
很多业务场景需要依赖反射机制,比如:RPC、Web MVC、对象序列化等