Java反射机制
关键词:
Introspection(内省、内观)
Reflection(反射)
##反射机制是java的高级技巧,世界上著名的框架struts,hibernate,spring的实现,无不用到了反射机制,反射机制可以让代码灵活,从而实现可配置化。
##Reflection
这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
##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是Reflection故事起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs。这些APIs将在稍后的探险活动中一一亮相。
##"Class” object的取得途径
Java允许我们从多种管道为一个class生成对应的Class object
1.getClass(),每个class 都有此函数
示例 String str = "abc";
Class c1 = str.getClass();
2.Class.getSuperclass()
示例 Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
3.运用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");
4.运用.class 语法
示例 Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
5.运用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 Reflection API 运用示例
Class c = Class.forName("");
c.getPackage();//得到Package
c.getDeclaredFields//得到类的所有字段
c.getDeclaredConstructors();//得到类的所有构造函数
c.getDeclaredMethods();();//得到类的所有方法
。。。其他不详细描述,查询java api即可
##
找出class参用(导入)的所有classes
没有直接可用的Reflection API可以为我们找出某个class参用的所有其它classes。要获得这项信息,必须做苦工,一步一脚印逐一记录。我们必须观察所有fields的类型、所有methods(包括constructors)的参数类型和回返类型,剔除重复,留下唯一。这正是为什么图5-2程序代码要为tName()指定一个hashtable(而非一个null)做为第二自变量的缘故:hashtable可为我们储存元素(本例为字符串),又保证不重复。
本文讨论至此,几乎可以还原一个class的原貌(唯有methods 和ctors的定义无法取得)。接下来讨论Reflection 的另三个动态性质:(1) 运行时生成instances,(2) 执
行期唤起methods,(3) 运行时改动fields。
运行时生成instances
欲生成对象实体,在Reflection 动态机制中有两种作法,一个针对“无自变量ctor”,
一个针对“带参数ctor”。图6是面对“无自变量ctor”的例子。如果欲调用的是“带参数ctor“就比较麻烦些,图7是个例子,其中不再调用Class的newInstance(),而是调用Constructor 的newInstance()。图7首先准备一个Class[]做为ctor的参数类型(本例指定为一个double和一个int),然后以此为自变量调用getConstructor(),获得一个专属ctor。接下来再准备一个Object[] 做为ctor实参值(本例指定3.14159和125),调用上述专属ctor的newInstance()。
#001 Class c = Class.forName("DynTest");
#002 Object obj = null;
#003 obj = c.newInstance(); //不带自变量
#004 System.out.println(obj);
图6:动态生成“Class object 所对应之class”的对象实体;无自变量。
#001 Class c = Class.forName("DynTest");
#002 Class[] pTypes = new Class[] { double.class, int.class };
#003 Constructor ctor = c.getConstructor(pTypes);
#004 //指定parameter list,便可获得特定之ctor
#005
#006 Object obj = null;
#007 Object[] arg = new Object[] {3.14159, 125}; //自变量
#008 obj = ctor.newInstance(arg);
#009 System.out.println(obj);
图7:动态生成“Class object 对应之class”的对象实体;自变量以Object[]表示。
运行时调用methods
这个动作和上述调用“带参数之ctor”相当类似。首先准备一个Class[]做为ctor的参数类型(本例指定其中一个是String,另一个是Hashtable),然后以此为自变量调用getMethod(),获得特定的Method object。接下来准备一个Object[]放置自变量,然后调用上述所得之特定Method object的invoke(),如图8。知道为什么索取Method object时不需指定回返类型吗?因为method overloading机制要求signature(署名式)必须唯一,而回返类型并非signature的一个成份。换句话说,只要指定了method名称和参数列,就一定指出了一个独一无二的method。
#001 public String func(String s, Hashtable ht)
#002 {
#003 …System.out.println("func invoked"); return s;
#004 }
#005 public static void main(String args[])
#006 {
#007 Class c = Class.forName("Test");
#008 Class ptypes[] = new Class[2];
#009 ptypes[0] = Class.forName("java.lang.String");
#010 ptypes[1] = Class.forName("java.util.Hashtable");
#011 Method m = c.getMethod("func",ptypes);
#012 Test obj = new Test();
#013 Object args[] = new Object[2];
#014 arg[0] = new String("Hello,world");
#015 arg[1] = null;
#016 Object r = m.invoke(obj, arg);
#017 Integer rval = (String)r;
#018 System.out.println(rval);
#019 }
图8:动态唤起method
运行时变更fields内容
与先前两个动作相比,“变更field内容”轻松多了,因为它不需要参数和自变量。首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set(),如图9。
#001 public class Test {
#002 public double d;
#003
#004 public static void main(String args[])
#005 {
#006 Class c = Class.forName("Test");
#007 Field f = c.getField("d"); //指定field 名称
#008 Test obj = new Test();
#009 System.out.println("d= " + (Double)f.get(obj));
#010 f.set(obj, 12.34);
#011 System.out.println("d= " + obj.d);
#012 }
#013 }
分享到:
相关推荐
Java反射机制是Java编程语言中的一个重要特性,它赋予了程序在运行时检查和操作类、接口、字段和方法的能力。这种动态类型的行为使得Java在某种程度上具有了类似于Perl、Python和Ruby等动态语言的灵活性。 Java反射...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...
Java反射机制是Java编程语言中的一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法的信息。这种动态类型的能力使得Java能够实现一些静态编译时无法完成的功能,增强了程序的灵活性和可扩展性。在...
侯捷先生是一位著名的Java技术专家,他的"流星絮语"系列教程深入浅出地讲解了Java反射机制。通过他的学习笔记,我们可以更深入地理解如何在实际项目中应用反射,解决一些特定问题,如插件化开发、序列化、动态代理等...
Java反射机制是Java被视为动态语言的关键特性之一,它允许程序在运行时通过Reflection APIs获取任何已知名称的类的内部信息。这一机制使得开发者能够在运行时检查类的修饰符(如public、static等)、超类(如Object...
- **设计模式**:在2005年的JavaTwo大会上,侯捷曾介绍过设计模式在Java标准库中的应用,特别是Command模式,它是实现Undoable功能的基础。 - **Undoable APIs**:这些APIs属于Swing框架的一部分,提供了复杂的机制...
8. **反射**:反射机制是Java的动态特性之一,允许程序在运行时检查和操作类、接口和对象。书中解释了如何通过反射API获取类信息,创建和调用对象,以及动态修改类的行为。 9. **枚举和注解**:书中介绍了Java的...
《Java编程思想》是Java开发领域的一本经典著作,由美国著名程序员Bruce Eckel撰写,侯捷翻译的中文版在中文读者中广受欢迎。这本书深入浅出地介绍了Java语言的核心概念和技术,对于初学者和有经验的开发者来说,都...
侯捷是一位知名的IT技术作家,尤其在Java领域有着深厚的造诣。他翻译的三本Java书籍,无疑为中国的Java开发者提供了宝贵的参考资料。这些书籍中的例子代码涵盖了广泛的Java编程概念和技术,帮助读者深入理解语言特性...
### 侯捷-Java编程思想+第2版(繁体版)关键知识点解析 #### 一、书籍概览与评价 - **书籍名称**:本书名为《Thinking in Java》第二版,作者为Bruce Eckel,台湾译者为侯捷与王建兴。 - **书籍定位**:本书被广泛...
8. **Java标准库API**:书中会涵盖Java API的常用部分,如日期时间API、并发工具类、反射机制等。 9. **JVM与内存管理**:讲解Java虚拟机的工作原理,包括类加载机制、垃圾收集以及性能优化。 10. **单元测试与...
3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可缺少的参考书 3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可缺少的参考书 3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可...
3本侯捷写的JAVA书(强烈推荐) 不要资源分,给那些么没有积分的人下载
4. **基础语法与面向对象编程**:侯捷的书籍可能会涵盖Java的基础知识,如变量、数据类型、流程控制语句、类与对象、继承、封装、多态等,这些都是Java编程的基石。 5. **异常处理**:Java的异常处理是其特有的一...
Java作为一门广泛使用的编程语言,其高级编程内容涵盖了众多领域,包括但不限于面向...侯捷的《java反射机制》.pdf是一个很好的起点,它将引导你深入理解Java反射的奥秘,而其他高级主题的学习则需要不断实践和探索。
这本书很经典,就不多介绍了
Reflection 是Java 被視為動態(或準動態)語言的㆒個關鍵性質。這個機制允許程 式在執行期透過Reflection APIs 取得任何㆒個已知名稱的class 的內部資訊,包括 其modifiers(諸如public, static 等等)、superclass...
《Thinking in Java》是由Bruce Eckel编著,侯捷翻译的Java编程经典教程。这本书深入浅出地介绍了Java语言的核心概念和技术,对于学习和理解Java编程有着极高的价值。在这个侯捷翻译的版本中,作者以清晰易懂的语言...
### Think in Java 2 侯捷翻译版 #### 核心知识点概览 - **书籍评价与推荐**:本书被广泛认为是Java编程语言学习领域的一本顶级教材,获得了来自不同背景专业人士的高度赞誉。 - **作者及译者介绍**:原著作者...