反射和RTTI
- RTTI: Run-Time Type Indentification, 运行时类型识别. 并非Java体系中的概念, 来自Thinking in C++
- Reflection(反射): 允许在程序运行期间探知并分析类对象的结构.
RTTI(Run-Time Type Identification)运行时类型识别。在《Thinking in Java》一书第十四章中有提到,其作用是在运行时识别一个对象的类型和类的信息。主要有两种方式:一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时发现和使用类的信息。
Class 类 & Class 对象
每个类实例都有一个相对应的”Class 对象”, 所以类实例在进行向上转型时不会丢失原有的类型信息, 这个 Class 对象的类型就是”Class 类”, 位于 java.lang.Class
;
T.class
: 获取类型 T 的 Class 对象, 基本类型int
也可以通过int.class
获取, 虽然 int 等基本类型不是类, 但是也可以Class cl = int.class;
t.getClass()
: 返回的也是 Class 对象,getClass()
是 Object 类的方法;可以用
==
判断两个obj的 class 是否来自同一个 class 对象:if(a.getClass() == A.class)
;
JVM 通过 ClassLoader 从 .class 文件中加载并创建 class 对象 Advanced-Java.04.ClassLoader
用反射创建类
// 方式1: |
使用反射API分析类
Class, Constructor(构造方法), Field(属性), Method(方法), Modifier(作用域)
Class cl = Class.forName("orj.xxx.ClassName"); |
使用反射API调用方法
Test test = (Test) clazz.newInstance(); |
Class类的方法列表
Class<?> forName(String className)
Class<?> forName(String name, boolean initialize, ClassLoader loader)
T newInstance()
:boolean isInstance(Object)
: Native方法, 注意区别instanceof
二元操作符boolean isArray()
: 是否是数组, Native方法Class<?> getComponentType()
: 返回Class类型, 返回的Class是数组元素的类型, 示例代码:String[].class.getComponentType()
Method getMethod(String name, Class<?>... parameterTypes)
: 返回指定方法名和形参的方法- 以下用来获取构造器/方法/属性的列表:
Constructor[] getDeclaredConstructors()
Method[] getDeclaredMethods()
Field[] getDeclaredFields()
数组和反射
java.lang.reflect.Array
类提供了数组的反射方法, 注意区分java.util.Arrays
用反射创建数组
// Array.newInstance 创建数组 |
用反射分析数组
// Class.getComponentType 获取数组元素类型 |
reflect.Array类的方法列表
Object newInstance(Class<?> componentType, int length)
- reflect.Array并没有探测数组元素类型, 和数组长度的方法:(
Class
类提供了一个:array.getClass().getComponentType().toString());
int Array.getLength(Object arr)
: 返回值是int, 数组大小最大只能是int ?- …
反射的使用场景
使用到 class.