随笔 - 100  文章 - 50  trackbacks - 0
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

我收藏的一些文章!

搜索

  •  

最新评论

阅读排行榜

评论排行榜

如果我们要在程序运行时动态地加载某个类,我们应该如何做呢?将要用到Reflection API,通过这种机制,我们可以而不知道类的名字,而得到类的所有函数的名字和类型,以及所有的数据成员的格式,而且,我们可以通过某些机制来动态的调用。通过Reflection API,可以实现强大的功能,就如同一个巨大的黑洞,可以接受一切东西,不管你是什么形态。事实上,编译器,GUI,甚至是接口,都用到了Reflection。
   Reflection的基本功能是什么呢?1.运行时生成类的实例(instance),2.执行期间调用方法(Method),3.运行时修改数据成员(field)。
   要实现这么强大的功能,首先必须了解Class类,Class在这里是单独的一个类,它位于java.lang包中,它用以描述程序的接口和类等信息,它本身没有构造函数,但是可以通过以下三种方法获得一个Class类的对象,它与某一个类或接口相关联。
对于任何类的对象,可以通过 Class object=对象名.getClass()的方式,getClass()函数是Object类中的成员函数。
Class object=Class.forName(类名);forName()是Class类的一个静态成员函数
通过Class object=类名.class语法,对于基本数据类型(Primitive)的封装类,可以通过类名.TYPE语法,这一点比较特殊。
   事实上,如果一个Class类的对象关联了某一个类,那么可以通过Class类的成员newInstance()来利用关联类的默认构造函数(即无参构造函数)来声明该类的一个对象。但是如果要调用带参数的构造函数,就要用到其他的方法。具体的步骤如下:
1.Class 对象与某类相关联。
声明用一个Class数组,(如parameter[])包含需要调用的构造函数所需要的参数类型信息
调用Class类的getConstrutor(parameter)来寻找合适的构造函数,把他的值返回给一个Construtor的对象(此处设为cons),Constructor类在java.lang.reflect包下,需要单独加载。
声明一个Object类的对象数组(此处设为 arg[]),这是实际参数。
利用cons.newInstance(arg),即可获得一个对应类的对象。(该函数位于java.lang.reflect.Constructor类中)
   动态调用成员函数的方法与之类似,不过对应的Constructor对象必须更改为一个Method类对象,Method类也在java.lang.reflect包中。它可以通过调用java.lang.reflect.Method类下的invoke(对象名,实参),形式调用某个函数,这里并不需要声明返回值,这一切交给JVM完成。它返回的值也是唯一确定的。
   动态修改数据成员时,首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set().

   以下代码除了动态调用函数和动态修改数据成员外,实现了全部本文提到的内容,并在jdk1.5中运行通过。
import java.lang.reflect.*;
class ReflectTest
{
 public static void main(String[] args)
 {
  if(args.length!=0)
  {
     Class flag=null;
     try
     {
      flag=Class.forName(args[0]);
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     Constructor[] cons=null;
     try
     {
      cons=flag.getDeclaredConstructors();
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     Method[]  meth=null;
     try
     {
      meth=flag.getDeclaredMethods();         
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     for(int i=0;i<cons.length;i++)     
     {
      System.out.println(cons[i].getName()); 
     }
     for(int i=0;i<meth.length;i++)
     {
      System.out.println(meth[i].getName());
     }
     System.out.println("---------------------------");
     Object o1=null;
     try
     {
      o1=flag.newInstance();
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     System.out.println(o1.toString());
     Class[] parameters=new Class[]{String.class};
     Constructor constr=null;
     try
     {
      constr=flag.getConstructor(parameters);
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     Object o2=null;
     Object[] o3=new Object[]{"HongMei"};
     try
     {
      o2=constr.newInstance(o3);
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     System.out.println(o2);
  }                                        
  else
  {
    System.out.println("We cant got parameter");
  }     
 }
}

class Cigarette
{
 static
 {
  System.out.println("Class Cigarette is loaded now");
 }
 Cigarette()
 {
 }
 public Cigarette(String str)
 {
  this.logo=str;
 }
 public void smoke()
 {
  System.out.println("smoke feels good");
 }
 public void lighterType(String type)
 {
  System.out.println(type);
 }
 String logo;
 public String toString()
 {
  return "Cigarette type is "+logo;
 }



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1746387

posted on 2007-08-31 10:20 fly 阅读(268) 评论(0)  编辑  收藏 所属分类: java学习

只有注册用户登录后才能发表评论。


网站导航: