运行时生成instances<o:p></o:p>
欲生成对象实体,在Reflection 动态机制中有两种作法,一个针对“无自变量ctor”,<o:p></o:p>
一个针对“带参数ctor”。图6是面对“无自变量ctor”的例子。如果欲调用的是“带参数ctor“就比较麻烦些,图7是个例子,其中不再调用Class的newInstance(),而是调用Constructor 的newInstance()。图7首先准备一个Class[]做为ctor的参数类型(本例指定为一个double和一个int),然后以此为自变量调用getConstructor(),获得一个专属ctor。接下来再准备一个Object[] 做为ctor实参值(本例指定3.14159和125),调用上述专属ctor的newInstance()。<o:p></o:p>
<o:p> </o:p>
#001 Class c = Class.forName("DynTest");<o:p></o:p>
#002 Object obj = null;<o:p></o:p>
#003 obj = c.newInstance(); //不带自变量<o:p></o:p>
#004 System.out.println(obj);<o:p></o:p>
图6:动态生成“Class object 所对应之class”的对象实体;无自变量。<o:p></o:p>
<o:p> </o:p>
#001 Class c = Class.forName("DynTest");<o:p></o:p>
#002 Class[] pTypes = new Class[] { double.class, int.class };<o:p></o:p>
#003 Constructor ctor = c.getConstructor(pTypes);<o:p></o:p>
#004 //指定parameter list,便可获得特定之ctor<o:p></o:p>
#005<o:p></o:p>
#006 Object obj = null;<o:p></o:p>
#007 Object[] arg = new Object[] {3.14159, 125}; //自变量<o:p></o:p>
#008 obj = ctor.newInstance(arg);<o:p></o:p>
#009 System.out.println(obj);<o:p></o:p>
图7:动态生成“Class object 对应之class”的对象实体;自变量以Object[]表示。<o:p></o:p>
<o:p> </o:p>
运行时调用methods<o:p></o:p>
这个动作和上述调用“带参数之ctor”相当类似。首先准备一个Class[]做为ctor的参数类型(本例指定其中一个是String,另一个是Hashtable),然后以此为自变量调用getMethod(),获得特定的Method object。接下来准备一个Object[]放置自变量,然后调用上述所得之特定Method object的invoke(),如图8。知道为什么索取Method object时不需指定回返类型吗?因为method overloading机制要求signature(署名式)必须唯一,而回返类型并非signature的一个成份。换句话说,只要指定了method名称和参数列,就一定指出了一个独一无二的method。<o:p></o:p>
<o:p> </o:p>
#001 public String func(String s, Hashtable ht)<o:p></o:p>
#002 {<o:p></o:p>
#003 …System.out.println("func invoked"); return s;<o:p></o:p>
#004 }<o:p></o:p>
#005 public static void main(String args[])<o:p></o:p>
#006 {<o:p></o:p>
#007 Class c = Class.forName("Test");<o:p></o:p>
#008 Class ptypes[] = new Class[2];<o:p></o:p>
#009 ptypes[0] = Class.forName("java.lang.String");<o:p></o:p>
#010 ptypes[1] = Class.forName("java.util.Hashtable");<o:p></o:p>
#011 Method m = c.getMethod("func",ptypes);<o:p></o:p>
#012 Test obj = new Test();<o:p></o:p>
#013 Object args[] = new Object[2];<o:p></o:p>
#014 arg[0] = new String("Hello,world");<o:p></o:p>
#015 arg[1] = null;<o:p></o:p>
#016 Object r = m.invoke(obj, arg);<o:p></o:p>
#017 Integer rval = (String)r;<o:p></o:p>
#018 System.out.println(rval);<o:p></o:p>
#019 }<o:p></o:p>
图8:动态唤起method<o:p></o:p>
<o:p> </o:p>
运行时变更fields内容<o:p></o:p>
与先前两个动作相比,“变更field内容”轻松多了,因为它不需要参数和自变量。首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set(),如图9。<o:p></o:p>
<o:p> </o:p>
#001 public class Test {<o:p></o:p>
#002 public double d;<o:p></o:p>
#003<o:p></o:p>
#004 public static void main(String args[])<o:p></o:p>
#005 {<o:p></o:p>
#006 Class c = Class.forName("Test");<o:p></o:p>
#007 Field f = c.getField("d"); //指定field 名称<o:p></o:p>
#008 Test obj = new Test();<o:p></o:p>
#009 System.out.println("d= " + (Double)f.get(obj));<o:p></o:p>
#<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="True" sourcevalue="10" unitname="F">010 f</st1:chmetcnv>.set(obj, 12.34);<o:p></o:p>
#011 System.out.println("d= " + obj.d);<o:p></o:p>
#012 }<o:p></o:p>
#013 }<o:p></o:p>
图9:动态变更field 内容<o:p></o:p>
分享到:
相关推荐
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...
7. **反射机制**:深入理解Java反射的概念,如何在运行时动态访问类、接口、方法和构造器。 8. **设计模式**:讲解常用的设计模式,如单例、工厂、观察者、装饰者、代理等,以及如何在实际开发中应用。 9. **JVM...
这篇《候捷谈Java反射机制》的文章应该深入探讨了这一主题。 反射的核心概念主要包括Class类、Constructor类、Method类和Field类。以下是对这些关键知识点的详细说明: 1. **Class类**:在Java中,每个类都有一个...
- **异常处理**:详细讲解Java中的异常处理机制,包括异常的抛出、捕获及处理策略,帮助开发者编写健壮的应用程序。 - **泛型与集合框架**:重点介绍了Java泛型的概念及其在集合框架中的应用,使开发者能够写出类型...
7. **反射机制**:利用反射动态获取类的信息,创建对象,调用方法,修改字段值,了解Class类和Method类的使用。 8. **设计模式**:常见的设计模式如工厂模式、单例模式、观察者模式、装饰者模式等,理解其应用场景...
8. **反射与动态代理**:Java的反射机制能让我们在运行时检查类的信息并操作对象,动态代理则能在运行时创建具有特定接口的代理类,这对于AOP(面向切面编程)和插件式系统很有用。 9. **Java EE基础**:虽然不是...
2. **Java技术**:精通Java核心技术,包括反射、集合、网络编程和IO流的使用。 3. **Web应用开发**:熟练运用jsp、servlet、JSTL/EL、dom4j和JDBC,具备Struts2、Spring、Hibernate等主流框架的实践经验。 4. **...