龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

JAVA反射机制实例教程(3)

时间:2014-09-20 11:08来源:网络整理 作者:网络 点击:
分享到:
文本到这里,所举的例子无一例外都与如何获取类的信息有关。我们也可以用 reflection 来做一些其它的事情,比如执行一个指定了名称的方法。下面的示例

文本到这里,所举的例子无一例外都与如何获取类的信息有关。我们也可以用 reflection 来做一些其它的事情,比如执行一个指定了名称的方法。下面的示例演示了这一操作:

import java.lang.reflect.*; 
public class Method2 { 
  public int add(int a, int b) { 
   return a + b; 
  } 
  public static void main(String args[]) { 
   try { 
      Class cls = Class.forName("Method2"); 
      Class partypes[] = new Class[2]; 
      partypes[0] = Integer.TYPE; 
      partypes[1] = Integer.TYPE; 
    
      Method meth = cls.getMethod("add", partypes); 
      Method2 methobj = new Method2(); 
      Object arglist[] = new Object[2]; 
      arglist[0] = new Integer(37); 
      arglist[1] = new Integer(47); 
      Object retobj = meth.invoke(methobj, arglist); 
      Integer retval = (Integer) retobj; 
      System.out.println(retval.intValue()); 
   } 
   catch (Throwable e) { 
      System.err.println(e); 
   } 
  } 
}

假如一个程序在执行的某处的时候才知道需要执行某个方法,这个方法的名称是在程序的运行过程中指定的 (例如,JavaBean 开发环境中就会做这样的事),那么上面的程序演示了如何做到。

上例中,getMethod用于查找一个具有两个整型参数且名为 add 的方法。找到该方法并创建了相应的Method 对象之后,在正确的对象实例中执行它。执行该方法的时候,需要提供一个参数列表,这在上例中是分别包装了整数 37 和 47 的两个 Integer 对象。执行方法的返回的同样是一个 Integer 对象,它封装了返回值 84。

7.创建新的对象

对于构造器,则不能像执行方法那样进行,因为执行一个构造器就意味着创建了一个新的对象 (准确的说,创建一个对象的过程包括分配内存和构造对象)。所以,与上例最相似的例子如下:

import java.lang.reflect.*; 
public class Constructor2 { 
  public Constructor2() { 
  } 
  public Constructor2(int a, int b) { 
   System.out.println("a = " + a + " b = " + b); 
  } 
  public static void main(String args[]) { 
   try { 
      Class cls = Class.forName("Constructor2"); 
      Class partypes[] = new Class[2]; 
      partypes[0] = Integer.TYPE; 
      partypes[1] = Integer.TYPE; 
      Constructor ct = cls.getConstructor(partypes); 
      Object arglist[] = new Object[2]; 
      arglist[0] = new Integer(37); 
      arglist[1] = new Integer(47); 
      Object retobj = ct.newInstance(arglist); 
   } 
   catch (Throwable e) { 
      System.err.println(e); 
   } 
  } 
}

根据指定的参数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象,而不是在编译的时候创建对象,这一点非常有价值。

8.改变字段(域)的值

reflection 的还有一个用处就是改变对象数据字段的值。reflection 可以从正在运行的程序中根据名称找到对象的字段并改变它,下面的例子可以说明这一点:

import java.lang.reflect.*; 
public class Field2 { 
  public double d; 
  public static void main(String args[]) { 
   try { 
      Class cls = Class.forName("Field2"); 
      Field fld = cls.getField("d"); 
      Field2 f2obj = new Field2(); 
      System.out.println("d = " + f2obj.d); 
      fld.setDouble(f2obj, 12.34); 
      System.out.println("d = " + f2obj.d); 
   } 
   catch (Throwable e) { 
      System.err.println(e); 
   } 
  } 
}

这个例子中,字段 d 的值被变为了 12.34。

9.使用数组

本文介绍的 reflection 的最后一种用法是创建的操作数组。数组在 Java 语言中是一种特殊的类类型,一个数组的引用可以赋给 Object 引用。观察下面的例子看看数组是怎么工作的:

import java.lang.reflect.*; 
public class Array1 { 
  public static void main(String args[]) { 
   try { 
      Class cls = Class.forName("java.lang.String"); 
      Object arr = Array.newInstance(cls, 10); 
      Array.set(arr, 5, "this is a test"); 
      String s = (String) Array.get(arr, 5); 
      System.out.println(s); 
   } 
   catch (Throwable e) { 
      System.err.println(e); 
   } 
  } 
}

例中创建了 10 个单位长度的 String 数组,为第 5 个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来。

下面这段代码提供了一个更复杂的例子:

import java.lang.reflect.*; 
public class Array2 { 
  public static void main(String args[]) { 
   int dims[] = new int[]{5, 10, 15}; 
   Object arr = Array.newInstance(Integer.TYPE, dims); 
   Object arrobj = Array.get(arr, 3); 
   Class cls = arrobj.getClass().getComponentType(); 
   System.out.println(cls); 
   arrobj = Array.get(arrobj, 5); 
   Array.setInt(arrobj, 10, 37); 
   int arrcast[][][] = (int[][][]) arr; 
   System.out.println(arrcast[3][5][10]); 
  } 
}

精彩图集

赞助商链接