本文共 2003 字,大约阅读时间需要 6 分钟。
动态语言是一种指程序在运行时可以修改其结构的语言。例如,JavaScript 和 Python 就是典型的动态语言,而 Java 则属于半动态语言。与动态语言相反,静态语言如 C 和 C++ 的结构在编译时已经确定,无法在运行时绑定。
反射机制在 Java 中具有特殊意义。它允许在程序运行时,根据类的实际类型获取信息,这对处理动态类(如外部加载的类)尤为重要。
反射机制的核心是通过反射可以获取类的信息:
反射的实现依赖于 Class 对象,其中 Class 对象描述了类的信息。这个 Class 对象是在类加载器(ClassLoader)动态加载时获取的。
在编译时,可使用的类型称为编译时类型,而运行时根据实际对象决定的类型称为运行时类型。例如:
Person p = new Student();
对于编译型 Person
和运行时类型 Student
,反射机制能提供运行时类型的信息。
当程序需要处理一些外部传入的对象时,例如通过反射获取其真实方法和属性,编译时无法预知该对象的具体类型,这种情况下反射显得尤为重要。
获取 Class 对象的方法有三种:
p.getClass()
获取当前对象的类。Person.class
获取已知类的信息。Class.forName("完整包名.ClassName")
动态加载类。通过类,可以获取类中的信息,如成员变量、方法和构造函数。
Class
的 getConstructor
方法获取指定构造函数。getDeclaredField
获取类中的属性。setAccessible
方法取消封装,例如修改私有字段。getDeclaredMethod
获取指定方法。setAccessible
解除访问限制。Person p = new Person(); Class clazz = p.getClass();
Class clazz = Person.class;
Class clazz = Class.forName("包名.ClassName");
通过获取 Class 对象,可以进一步获取或修改类的成员信息。
权限问题:
父类信息获取:
getField
只能获取公有属性。getSuperclass
获取父类引用后,可以通过 getDeclaredField
获取父类的所有属性。静态方法反射:
null
作为目标对象。泛型参数反射:
Object
类型。jOOR 是一个开源反射框架,提供了更简单的反射操作接口,但依赖 Apache Commons 代码库。
通过 newInstance() 创建对象时,需确保类有默认空构造函数。
Class clazz = Class.forName("reflection.Person");Object person = clazz.newInstance();
Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);
Object person = constructor.newInstance("张三", 30);
通过反射,可以灵活调用任意构造函数,实现高度的分类控制。
反射机制为 Java 提供了动态操作类、成员和构造的能力。在编解析式式的应用以及动态加载类的场景中尤为重要。
转载地址:http://uqurz.baihongyu.com/