`
huntersp
  • 浏览: 41078 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA反射基础(摘抄自"侯捷谈JAVA反射机制")

    博客分类:
  • JAVA
阅读更多
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编程语言中的一个重要特性,它赋予了程序在运行时检查和操作类、接口、字段和方法的能力。这种动态类型的行为使得Java在某种程度上具有了类似于Perl、Python和Ruby等动态语言的灵活性。 Java反射...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    侯捷谈java反射机制.doc

    Java反射机制是Java编程语言中的一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法的信息。这种动态类型的能力使得Java能够实现一些静态编译时无法完成的功能,增强了程序的灵活性和可扩展性。在...

    Reflection_in_Java.zip_in_java 反射_java 反射机制_java反射_反射机制

    侯捷先生是一位著名的Java技术专家,他的"流星絮语"系列教程深入浅出地讲解了Java反射机制。通过他的学习笔记,我们可以更深入地理解如何在实际项目中应用反射,解决一些特定问题,如插件化开发、序列化、动态代理等...

    JAVA反射侯捷观点

    Java反射机制是Java被视为动态语言的关键特性之一,它允许程序在运行时通过Reflection APIs获取任何已知名称的类的内部信息。这一机制使得开发者能够在运行时检查类的修饰符(如public、static等)、超类(如Object...

    设计模式Java-侯捷

    - **设计模式**:在2005年的JavaTwo大会上,侯捷曾介绍过设计模式在Java标准库中的应用,特别是Command模式,它是实现Undoable功能的基础。 - **Undoable APIs**:这些APIs属于Swing框架的一部分,提供了复杂的机制...

    侯捷-java编程思想.pdf

    8. **反射**:反射机制是Java的动态特性之一,允许程序在运行时检查和操作类、接口和对象。书中解释了如何通过反射API获取类信息,创建和调用对象,以及动态修改类的行为。 9. **枚举和注解**:书中介绍了Java的...

    Java编程思想侯捷编译第二版

    《Java编程思想》是Java开发领域的一本经典著作,由美国著名程序员Bruce Eckel撰写,侯捷翻译的中文版在中文读者中广受欢迎。这本书深入浅出地介绍了Java语言的核心概念和技术,对于初学者和有经验的开发者来说,都...

    侯捷翻译的3本JAVA书的例子代码

    侯捷是一位知名的IT技术作家,尤其在Java领域有着深厚的造诣。他翻译的三本Java书籍,无疑为中国的Java开发者提供了宝贵的参考资料。这些书籍中的例子代码涵盖了广泛的Java编程概念和技术,帮助读者深入理解语言特性...

    侯捷-Java编程思想+第2版(繁体版)

    ### 侯捷-Java编程思想+第2版(繁体版)关键知识点解析 #### 一、书籍概览与评价 - **书籍名称**:本书名为《Thinking in Java》第二版,作者为Bruce Eckel,台湾译者为侯捷与王建兴。 - **书籍定位**:本书被广泛...

    Practical Java (侯捷 刘永丹译-超星版

    8. **Java标准库API**:书中会涵盖Java API的常用部分,如日期时间API、并发工具类、反射机制等。 9. **JVM与内存管理**:讲解Java虚拟机的工作原理,包括类加载机制、垃圾收集以及性能优化。 10. **单元测试与...

    3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可缺少的参考书

    3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可缺少的参考书 3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可缺少的参考书 3本侯捷写的JAVA书(强烈推荐)--非常经典的书,java学者不可...

    3本侯捷写的JAVA书(强烈推荐

    3本侯捷写的JAVA书(强烈推荐) 不要资源分,给那些么没有积分的人下载

    3本侯捷写的JAVA书(强烈推荐)

    4. **基础语法与面向对象编程**:侯捷的书籍可能会涵盖Java的基础知识,如变量、数据类型、流程控制语句、类与对象、继承、封装、多态等,这些都是Java编程的基石。 5. **异常处理**:Java的异常处理是其特有的一...

    Java高级编程核心内容讲解大全

    Java作为一门广泛使用的编程语言,其高级编程内容涵盖了众多领域,包括但不限于面向...侯捷的《java反射机制》.pdf是一个很好的起点,它将引导你深入理解Java反射的奥秘,而其他高级主题的学习则需要不断实践和探索。

    Thinking in JAVA(中文侯捷译)

    这本书很经典,就不多介绍了

    侯捷讲Java的reflection机制

    Reflection 是Java 被視為動態(或準動態)語言的㆒個關鍵性質。這個機制允許程 式在執行期透過Reflection APIs 取得任何㆒個已知名稱的class 的內部資訊,包括 其modifiers(諸如public, static 等等)、superclass...

    thinking-in-java-侯捷翻译版

    《Thinking in Java》是由Bruce Eckel编著,侯捷翻译的Java编程经典教程。这本书深入浅出地介绍了Java语言的核心概念和技术,对于学习和理解Java编程有着极高的价值。在这个侯捷翻译的版本中,作者以清晰易懂的语言...

    Think in java 2 侯捷翻译版

    ### Think in Java 2 侯捷翻译版 #### 核心知识点概览 - **书籍评价与推荐**:本书被广泛认为是Java编程语言学习领域的一本顶级教材,获得了来自不同背景专业人士的高度赞誉。 - **作者及译者介绍**:原著作者...

Global site tag (gtag.js) - Google Analytics