Java 反射机制
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
java反射所需要的类
1.Class类:它的实例表示正在运行的java应用程序中的类和接口
2.Constructor类:提供 关于类的单个构造方法的信息以及对他的访问权限。
3.Method类:提供有关类或接口的单独的某个方法的信息
4.Array类:提 供动态创建数组或访问数组的静态方法。
5.Field类:提供有关类或接口的属性的信息,以及对他的动态访问权限。
“ Class ” class
Class class 十分特殊。它和一般 classes 一样继承自 Object ,其实体用以表达 Java 程序运行时的 classes 和 interfaces , 也用来表达 enum 、 array 、 primitive Java types ( boolean, byte, char, short, int, long, float, double )以及关键词 void 。当一个 class 被加载,或当加载器( class loader )的 defineClass() 被 JVM 调用, JVM 便自动产生一个 Class object 。如果您想借由 “ 修改 Java 标准库源码 ” 来 观察 Class object 的实际生成时机(例如在 Class 的 constructor 内添加一个 println() ),不能够!因为 Class 并没有 public constructor
“ Class ” object 的取得途径
Java 允许我们从多种管道为一个 class 生成对应的 Class object 。下图是 一份整理。
| Class object 诞生管道 | 示 例 |
| 运 用 getClass() 注: 每个 class 都有此函数 |
String str = “abc”; Class c1 = str.getClass(); |
| 运 用 Class.getSuperclass() 2 |
Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass(); |
| 运 用 static method Class.forName()(最 常被使用) |
Class c1 = Class.forName (“java.lang.String”); Class c2 = Class.forName (“java.awt.Button”); Class c3 = Class.forName (“java.util.LinkedList$Entry”); Class c4 = Class.forName (“I”); Class c5 = Class.forName (“[I"); |
| 运 用.class 语法 | Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; |
| 运 用 primitive wrapper classes 的 TYPE 语法 |
Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE; |
Java classes 各成份所对应的 Reflection APIs
其中出现的 Package 、 Method 、 Constructor 、Field 等等 classes ,都定义于 java.lang.reflect 。
| Java class 内部模块 | Java class 内部模块说明 | 相 应之 Reflection API ,多半为 Class methods 。 | 返 回值类型 (return type) |
| (1) package | class 隶属哪个 package | getPackage() | Package |
| (2) import | class 导入哪些 classes | 无 直接对应之 API 。 | |
| (3) modifier | class (或 methods, fields )的属性 | int getModifiers() Modifier.toString(int) Modifier.isInterface(int) |
int String bool |
| (4) class name or interface name | class/interface | 名 称 getName() | String |
| (5) type parameters | 参 数化类型的名称 | getTypeParameters() | TypeVariable <Class>[] |
| (6) base class | base class (只可能一个) | getSuperClass() | Class |
| (7) implemented interfaces | 实 现有哪些 interfaces | getInterfaces() | Class[] |
| (8) inner classes | 内 部 classes | getDeclaredClasses() | Class[] |
| (8′) outer class | 如 果我们观察的 class 本身是 inner classes ,那么相对它就会有个 outer class 。 | getDeclaringClass() | Class |
| (9) constructors | 构 造函数 getDeclaredConstructors() | 不 论 public 或 private 或其它 access level ,皆可获得。另有功能近似之取得函数。 | Constructor[] |
| (10) methods | 操 作函数 getDeclaredMethods() | 不 论 public 或 private 或其它 access level ,皆可获得。另有功能近似之取得函数。 | Method[] |
| (11) fields | 字 段(成员变量) | getDeclaredFields() 不论 public 或 private 或其它 access level ,皆可获得。另有功能近似之取得函数。 | Field[] |
Reflection 的另三个动态性质: (1) 运行时生成 instances , (2) 执行 期唤起 methods , (3) 运行时改动 fields 。
在网上找了一些关于反射的相关讲解,没有发现用详细代码加以注释说明反射的一些用法,看来还是不得不自己深入理解之后,自己写一些详细的使用方法,那时候 再把代码贴出来。
