﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-fcailiao-随笔分类-java_基础</title><link>http://www.blogjava.net/fcailiao/category/26390.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 07 Oct 2007 03:48:33 GMT</lastBuildDate><pubDate>Sun, 07 Oct 2007 03:48:33 GMT</pubDate><ttl>60</ttl><item><title>java反射机制[基础学习]</title><link>http://www.blogjava.net/fcailiao/archive/2007/10/07/150800.html</link><dc:creator>hanzao</dc:creator><author>hanzao</author><pubDate>Sun, 07 Oct 2007 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/fcailiao/archive/2007/10/07/150800.html</guid><wfw:comment>http://www.blogjava.net/fcailiao/comments/150800.html</wfw:comment><comments>http://www.blogjava.net/fcailiao/archive/2007/10/07/150800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/fcailiao/comments/commentRss/150800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fcailiao/services/trackbacks/150800.html</trackback:ping><description><![CDATA[[来自]http://java.ccidnet.com/art/3737/20050409/454831_1.html<br />
<h3><font size="1">一、反射的概念 ：</font></h3>
<font size="1"></font>
<p><font size="1">Java中，反射是一种强大的工具。它使您能够创建灵活的代码，这些代码可以在运行时装配，无需在组件之间进行源代
表链接。反射允许我们在编写与执
行时，使我们的程序代码能够接入装载到JVM中的类的内部信息，而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的
是：如果使用不当，反射的成本很高。</font></p>
<h3><font size="1">二、Java中的类反射：</font></h3>
<p><font size="1">Reflection 是 Java 程序开发语言的特征之一，它允许运行中的 Java
程序对自身进行检查，或者说&#8220;自审&#8221;，并能直接操作程序 的内部属性。Java
的这一能力在实际应用中也许用得不是很多，但是在其它的程序设计语言中根本就不存在这一特性。例如，Pascal、C 或者 C+ +
中就没有办法在程序中获得函数定义相关的信息。</font></p>
<p><font size="1"><strong>1</strong><strong>．检测类：</strong></font></p>
<p><font size="1"><strong>1.1 reflection</strong><strong>的工作机制</strong></font></p>
<p><font size="1">考虑下面这个简单的例子，让我们看看 reflection 是如何工作的。</font></p>
<p><font size="1">import java.lang.reflect.*;<br />
public class DumpMethods {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Class c = Class.forName(args[0]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Method m[] = c.getDeclaredMethods();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; m.length; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  System.out.println(m[i].toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
}</font></p>
<p><font size="1">按如下语句执行：</font></p>
<p><font size="1">java DumpMethods java.util.Stack</font></p>
<p><font size="1">它的结果输出为：</font></p>
<p><font size="1">public java.lang.Object java.util.Stack.push(java.lang.Object)</font></p>
<p><font size="1">public synchronized java.lang.Object java.util.Stack.pop()</font></p>
<p><font size="1">public synchronized java.lang.Object java.util.Stack.peek()</font></p>
<p><font size="1">public boolean java.util.Stack.empty()</font></p>
<p><font size="1">public synchronized int java.util.Stack.search(java.lang.Object)</font></p>
<p><font size="1">这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。</font></p>
<p><font size="1">这个程序使用 Class.forName 载入指定的类，然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。</font></p>
<p><font size="1"><strong>1.2 Java</strong><strong>类反射中的主要方法</strong></font></p>
<p><font size="1">对于以下三类组件中的任何一类来说 -- 构造函数、字段和方法 -- java.lang.Class 提供四种独立的反射调用，以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射调用：</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数，</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Constructor[] getConstructors() -- 获得类的所有公共构造函数</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) </font></p>
<p><font size="1">获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用，在参数类型数组中使用了字段名：</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Field getField(String name) -- 获得命名的公共字段</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Field[] getFields() -- 获得类的所有公共字段</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Field getDeclaredField(String name) -- 获得类声明的命名的字段</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Field[] getDeclaredFields() -- 获得类声明的所有字段 </font></p>
<p><font size="1">用于获得方法信息函数：</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Method getMethod(String name, Class[] params) -- 使用特定的参数类型，获得命名的公共方法</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Method[] getMethods() -- 获得类的所有公共方法</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型，获得类声明的命名的方法</font></p>
<p><font size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   Method[] getDeclaredMethods() -- 获得类声明的所有方法 </font></p>
<p><font size="1"><strong>1.3</strong><strong>开始使用 Reflection：</strong></font></p>
<span id="zoom">
<p><font size="1">用于 reflection 的类，如 Method，可以在
java.lang.relfect 包中找到。使用这些类的时候必须要遵循三个步骤：第一步是获得你想操作的类的 java.lang.Class
对象。在运行中的 Java 程序中，用 java.lang.Class 类来描述类和接口等。</font></p>
<p><font size="1">下面就是获得一个 Class 对象的方法之一：</font></p>
<p><font size="1">Class c = Class.forName("java.lang.String");</font></p>
<p><font size="1">这条语句得到一个 String 类的类对象。还有另一种方法，如下面的语句：</font></p>
<p><font size="1">Class c = int.class;</font></p>
<p><font size="1">或者</font></p>
<p><font size="1">Class c = Integer.TYPE;</font></p>
<p><font size="1">它们可获得基本类型的类信息。其中后一种方法中访问的是基本类型的封装类 (如 Integer) 中预先定义好的 TYPE 字段。</font></p>
<p><font size="1">第二步是调用诸如 getDeclaredMethods 的方法，以取得该类中定义的所有方法的列表。</font></p>
<p><font size="1">一旦取得这个信息，就可以进行第三步了——使用 reflection API 来操作这些信息，如下面这段代码：</font></p>
<p><font size="1">Class c = Class.forName("java.lang.String");</font></p>
<p><font size="1">Method m[] = c.getDeclaredMethods();</font></p>
<p><font size="1">System.out.println(m[0].toString());</font></p>
<p><font size="1">它将以文本方式打印出 String 中定义的第一个方法的原型。</font></p>
<p><font size="1">在下面的例子中，这三个步骤将为使用 reflection 处理特殊应用程序提供例证。</font></p>
<p><font size="1">模拟 instanceof 操作符</font></p>
<p><font size="1">得到类信息之后，通常下一个步骤就是解决关于 Class 对象的一些基本的问题。例如，Class.isInstance 方法可以用于模拟 instanceof 操作符：</font></p>
<p><font size="1">class A {<br />
}</font></p>
<p><font size="1">public class instance1 {<br />
&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("A");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean b1 = cls.isInstance(new Integer(37));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(b1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean b2 = cls.isInstance(new A());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(b2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">在这个例子中创建了一个 A 类的 Class 对象，然后检查一些对象是否是 A 的实例。Integer(37) 不是，但 new A() 是。</font></p>
<p><span id="zoom">
<p><strong><font size="1">1.4 找出类的方法</font></strong></p>
<p><font size="1">找出一个类中定义了些什么方法，这是一个非常有价值也非常基础的 reflection 用法。下面的代码就实现了这一用法：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class method1 {<br />
&nbsp;&nbsp; private int f1(Object p, int x) throws NullPointerException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new NullPointerException();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x;<br />
&nbsp;&nbsp; }</font></p>
<p><font size="1">&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("method1");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method methlist[] = cls.getDeclaredMethods();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; methlist.length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method m = methlist[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("name = " + m.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("decl class = " + m.getDeclaringClass());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class pvec[] = m.getParameterTypes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; pvec.length; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("param #" + j + " " + pvec[j]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class evec[] = m.getExceptionTypes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; evec.length; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("exc #" + j + " " + evec[j]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("return type = " + m.getReturnType());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-----");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">这
个程序首先取得 method1 类的描述，然后调用 getDeclaredMethods 来获取一系列的 Method
对象，它们分别描述了定义在类中的每一个方法，包括 public 方法、protected 方法、package 方法和 private
方法等。如果你在程序中使用 getMethods 来代替 getDeclaredMethods，你还能获得继承来的各个方法的信息。</font></p>
<p><font size="1">取得了 Method 对象列表之后，要显示这些方法的参数类型、异常类型和返回值类型等就不难了。这些类型是基本类型还是类类型，都可以由描述类的对象按顺序给出。</font></p>
<p><font size="1">输出的结果如下：</font></p>
<p><font size="1">name = f1</font></p>
<p><font size="1">decl class = class method1</font></p>
<p><font size="1">param #0 class java.lang.Object</font></p>
<p><font size="1">param #1 int</font></p>
<p><font size="1">exc #0 class java.lang.NullPointerException</font></p>
<p><font size="1">return type = int</font></p>
<p><font size="1">-----</font></p>
<p><font size="1">name = main</font></p>
<p><font size="1">decl class = class method1</font></p>
<p><font size="1">param #0 class [Ljava.lang.String;</font></p>
<p><font size="1">return type = void</font></p>
<p><font size="1">-----</font></p>
<p><br />
<strong><span id="zoom"><span id="zoom"><font size="1">1.5 </font></span></span><font size="1">获取构造器信息</font></strong></p>
<p><font size="1">获取类构造器的用法与上述获取方法的用法类似，如：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class constructor1 {<br />
&nbsp;&nbsp; public constructor1() {<br />
&nbsp;&nbsp; }</font></p>
<p><font size="1">&nbsp;&nbsp; protected constructor1(int i, double d) {<br />
&nbsp;&nbsp; }</font></p>
<p><font size="1">&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("constructor1");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Constructor ctorlist[] = cls.getDeclaredConstructors();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; ctorlist.length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Constructor ct = ctorlist[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("name = " + ct.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("decl class = " + ct.getDeclaringClass());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class pvec[] = ct.getParameterTypes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; pvec.length; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("param #" + j + " " + pvec[j]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class evec[] = ct.getExceptionTypes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; evec.length; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("exc #" + j + " " + evec[j]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-----");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">这个例子中没能获得返回类型的相关信息，那是因为构造器没有返回类型。</font></p>
<p><font size="1">这个程序运行的结果是：</font></p>
<p><font size="1">name = constructor1</font></p>
<p><font size="1">decl class = class constructor1</font></p>
<p><font size="1">-----</font></p>
<p><font size="1">name = constructor1</font></p>
<p><font size="1">decl class = class constructor1</font></p>
<p><font size="1">param #0 int</font></p>
<p><font size="1">param #1 double</font></p>
<p><font size="1">-----</font></p>
<p><strong><font size="1">1.6获取类的字段(域)</font></strong></p>
<p><font size="1">找出一个类中定义了哪些数据字段也是可能的，下面的代码就在干这个事情：</font></p>
<p>例1：<br />
<font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class field1 {<br />
&nbsp;&nbsp; private double d;<br />
&nbsp;&nbsp; public static final int i = 37;<br />
&nbsp;&nbsp; String s = "testing";</font></p>
<p><font size="1">&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("field1");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field fieldlist[] = cls.getDeclaredFields();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; fieldlist.length; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field fld = fieldlist[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("name = " + fld.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("decl class = " + fld.getDeclaringClass());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("type = " + fld.getType());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int mod = fld.getModifiers();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("modifiers = " + Modifier.toString(mod));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-----");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">这
个例子和前面那个例子非常相似。例中使用了一个新东西 Modifier，它也是一个 reflection
类，用来描述字段成员的修饰语，如&#8220;private int&#8221;。这些修饰语自身由整数描述，而且使用 Modifier.toString
来返回以&#8220;官方&#8221;顺序排列的字符串描述 (如&#8220;static&#8221;在&#8220;final&#8221;之前)。这个程序的输出是：</font></p>
<p><font size="1">name = d</font></p>
<p><font size="1">decl class = class field1</font></p>
<p><font size="1">type = double</font></p>
<p><font size="1">modifiers = private</font></p>
<p><font size="1">-----</font></p>
<p><font size="1">name = i</font></p>
<p><font size="1">decl class = class field1</font></p>
<p><font size="1">type = int</font></p>
<p><font size="1">modifiers = public static final</font></p>
<p><font size="1">-----</font></p>
<p><font size="1">name = s</font></p>
<p><font size="1">decl class = class field1</font></p>
<p><font size="1">type = class java.lang.String</font></p>
<p><font size="1">modifiers =</font></p>
<p><font size="1">-----</font></p>
<p>例2:</p>
<p><span id="zoom"><span id="zoom"><font size="1">import java.lang.reflect.*;<br />
import java.awt.*;<br />
<br />
class SampleGet {<br />
<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Rectangle r = new Rectangle(100, 325);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printHeight(r);<br />
<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; static void printHeight(Rectangle r) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Field heightField;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Integer heightValue;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class c = r.getClass();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; heightField = c.getField("height");//取得height这个变量<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; heightValue = (Integer) heightField.get(r);//取得height这个变量的值<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("Height: " + heightValue.toString());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (NoSuchFieldException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (SecurityException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (IllegalAccessException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println(e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}</font></span></span></p>
<p><span id="zoom"><span id="zoom">输出: </span></span><span id="zoom"><span id="zoom"><span id="zoom"><span id="zoom"><font size="1">Height:325</font></span></span></span></span><br />
<font size="1"><br />
</font></p>
<p><font size="1">和获取方法的情况一下，获取字段的时候也可以只取得在当前类中申明了的字段信息 (getDeclaredFields)，或者也可以取得父类中定义的字段 (getFields) 。</font></p>
<p><br />
<strong><font size="1">1.7 根据方法的名称来执行方法</font></strong></p>
<p><font size="1">文本到这里，所举的例子无一例外都与如何获取类的信息有关。我们也可以用 reflection 来做一些其它的事情，比如执行一个指定了名称的方法。下面的示例演示了这一操作：</font></p>
<p><font size="1">例1:<br />
</font></p>
<p><font size="1">import java.lang.reflect.*;<br />
public class method2 {<br />
&nbsp;&nbsp; public int add(int a, int b) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return a + b;<br />
&nbsp;&nbsp; }<br />
&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("method2");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class partypes[] = new Class[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; partypes[0] = Integer.TYPE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; partypes[1] = Integer.TYPE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method meth = cls.getMethod("add", partypes);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; method2 methobj = new method2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object arglist[] = new Object[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arglist[0] = new Integer(37);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arglist[1] = new Integer(47);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object retobj = meth.invoke(methobj, arglist);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer retval = (Integer) retobj;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(retval.intvalue());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">假如一个程序在执行的某处的时候才知道需要执行某个方法，这个方法的名称是在程序的运行过程中指定的 (例如，JavaBean 开发环境中就会做这样的事)，那么上面的程序演示了如何做到。</font></p>
<p><font size="1">上
例中，getMethod 用于查找一个具有两个整型参数且名为 add 的方法。找到该方法并创建了相应的 Method
对象之后，在正确的对象实例中执行它。执行该方法的时候，需要提供一个参数列表，这在上例中是分别包装了整数 37 和 47 的两个 Integer
对象。执行方法的返回的同样是一个 Integer 对象，它封装了返回值 84。</font></p>
<p>例2：</p>
<p><font size="1">import java.lang.reflect.Method;<br />
<br />
//Base.java 抽象基类<br />
//Son1.java 基类扩展1<br />
//Son2.java 基类扩展2<br />
//Util.java <br />
<br />
//Base.java 抽象基类只是一个定义<br />
abstract class Base {<br />
<br />
}<br />
<br />
//Son1.java 是已经实现的Base<br />
class Son1 extends Base {<br />
&nbsp;&nbsp; &nbsp;private int id;<br />
<br />
&nbsp;&nbsp; &nbsp;private String name;<br />
<br />
&nbsp;&nbsp; &nbsp;public int getId() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return id;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setId(int id) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.id = id;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public String getName() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return name;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setName(String name) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.name = name;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void son1Method(String s) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s);<br />
&nbsp;&nbsp; &nbsp;}<br />
}<br />
<br />
// Son2.java 是已经实现的Base<br />
class Son2 extends Base {<br />
&nbsp;&nbsp; &nbsp;private int id;<br />
<br />
&nbsp;&nbsp; &nbsp;private double salary;<br />
<br />
&nbsp;&nbsp; &nbsp;public int getId() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return id;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setId(int id) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.id = id;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public double getSalary() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return salary;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public void setSalary(double salary) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; this.salary = salary;<br />
&nbsp;&nbsp; &nbsp;}<br />
}<br />
<br />
// Util.java 演示了如何根据指定的类名，类字段名和所对应的数据，得到一个类的实例<br />
public class Util {<br />
&nbsp;&nbsp; &nbsp;// 此方法的最大好处是没有类名Son1,Son2 可以通过参数来指定，程序里面根本不用出现<br />
&nbsp;&nbsp; &nbsp;public static Base utilDo(String beanName,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String methodName, String paraValue) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; Base base = null;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class cls = Class.forName(beanName);//生成类<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; base = (Base) cls.newInstance();//生成类的对象<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Class[] paraTypes = new Class[] { String.class};<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Method method = cls.getMethod(methodName, paraTypes);// fieldSetter为方法的名称;paraTypes为该方法的参数数组,要用类的形式<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String[] paraValues = new String[] { paraValue };<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; method.invoke(base, paraValues);//执行方法<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return base;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; Son1 son1 = (Son1) Util.utilDo("test.Reflection.Son1",<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "setName", "I am son1");// 表示类的字符串一定要是类的&#8220;全类名&#8221;,这里是</font><font size="1">test.Reflection.Son1</font><br />
<font size="1">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; System.out.println("son1.getName() :" + son1.getName());<br />
&nbsp;&nbsp; &nbsp;}<br />
}</font></p>
</span></p>
</span>
<p><font size="1">输出：son1.getName() :I am son1<br />
</font></p>
<span id="zoom">
<p><span id="zoom">
<p><strong><font size="1">1.8 创建新的对象</font></strong></p>
<p><font size="1">对于构造器，则不能像执行方法那样进行，因为执行一个构造器就意味着创建了一个新的对象 (准确的说，创建一个对象的过程包括分配内存和构造对象)。所以，与上例最相似的例子如下：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class constructor2 {<br />
&nbsp;&nbsp; public constructor2() {<br />
&nbsp;&nbsp; }</font></p>
<p><font size="1">&nbsp;&nbsp; public constructor2(int a, int b) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("a = " + a + " b = " + b);<br />
&nbsp;&nbsp; }</font></p>
<p><font size="1">&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("constructor2");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class partypes[] = new Class[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; partypes[0] = Integer.TYPE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; partypes[1] = Integer.TYPE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Constructor ct = cls.getConstructor(partypes);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object arglist[] = new Object[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arglist[0] = new Integer(37);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arglist[1] = new Integer(47);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object retobj = ct.newInstance(arglist);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">根据指定的参数类型找到相应的构造函数并执行它，以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象，而不是在编译的时候创建对象，这一点非常有价值。</font></p>
<p><strong><font size="1">1.9 改变字段(域)的值</font></strong></p>
<p><font size="1">reflection 的还有一个用处就是改变对象数据字段的值。reflection 可以从正在运行的程序中根据名称找到对象的字段并改变它，下面的例子可以说明这一点：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class field2 {<br />
&nbsp;&nbsp; public double d;</font></p>
<p><font size="1">&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("field2");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field fld = cls.getField("d");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; field2 f2obj = new field2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("d = " + f2obj.d);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fld.setDouble(f2obj, 12.34);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("d = " + f2obj.d);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">这个例子中，字段 d 的值被变为了 12.34。</font></p>
<p><strong><font size="1">1.10 使用数组</font></strong></p>
<p><font size="1">本文介绍的 reflection 的最后一种用法是创建的操作数组。数组在 Java 语言中是一种特殊的类类型，一个数组的引用可以赋给 Object 引用。观察下面的例子看看数组是怎么工作的：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class array1 {<br />
&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = Class.forName("java.lang.String");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object arr = Array.newInstance(cls, 10);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Array.set(arr, 5, "this is a test");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = (String) Array.get(arr, 5);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</font></p>
<p><font size="1">例中创建了 10 个单位长度的 String 数组，为第 5 个位置的字符串赋了值，最后将这个字符串从数组中取得并打印了出来。</font></p>
<p><font size="1">下面这段代码提供了一个更复杂的例子：</font></p>
<p><font size="1">import java.lang.reflect.*;</font></p>
<p><font size="1">public class array2 {<br />
&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int dims[] = new int[]{5, 10, 15};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object arr = Array.newInstance(Integer.TYPE, dims);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object arrobj = Array.get(arr, 3);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class cls = arrobj.getClass().getComponentType();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(cls);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrobj = Array.get(arrobj, 5);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Array.setInt(arrobj, 10, 37);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int arrcast[][][] = (int[][][]) arr;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(arrcast[3][5][10]);<br />
&nbsp;&nbsp; }<br />
}<br />
例
中创建了一个 5 x 10 x 15 的整型数组，并为处于 [3][5][10] 的元素赋了值为
37。注意，多维数组实际上就是数组的数组，例如，第一个 Array.get 之后，arrobj 是一个 10 x 15
的数组。进而取得其中的一个元素，即长度为 15 的数组，并使用 Array.setInt 为它的第 10 个元素赋值。</font></p>
<p><font size="1">注意创建数组时的类型是动态的，在编译时并不知道其类型。</font></p>
</span></p>
</span>
<img src ="http://www.blogjava.net/fcailiao/aggbug/150800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fcailiao/" target="_blank">hanzao</a> 2007-10-07 11:34 <a href="http://www.blogjava.net/fcailiao/archive/2007/10/07/150800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>