首页(162) xml(5) spring(1) 生活(8) java(70) 代码(10) 英语(4) 数据库(7) c#(14) 成长(10) 软件工程(27)  写新日志
 
 

玻璃杯中的花生壳

  真爱的事业和真正的爱情一生只有一次,都值得我们温柔地相待,因为那种感觉是永远都无法复制的, 这世界真正属于你的东西其实并不多,你不好好珍惜,它便会离你而去,包括机遇,包括爱情,包括生命。
   不要找任何理由,  当幸福在你身边的时候就抓住它,你就一定会很幸福! 
   

时 间 记 忆
«September 2025»
123456
78910111213
14151617181920
21222324252627
282930

最 新 评 论
回复:xml的Jdom解析过程详解
回复:突然想到的几句话!
 Boyle came out of n
回复:xml的Jdom解析过程详解
回复:配置Spring数据源
回复:使用SAX解析XML
回复:java中写文件操作时FileOu
回复:关联和依赖关系的区分
回复:HttpSessionListen
回复:Spring AOP四种创建通知(

最 新 日 志
Java开发者的十大戒律
配置Spring数据源
java多线程设计模式
java中switch的使用
性格,编码,测试
突然想到的几句话!
理解Spring AOP中的关键概念
Spring AOP四种创建通知(拦截器
xml的四种解析方法 比较 sax,do
xml的Jdom解析过程详解

最 新 留 言
签写新留言

我渴望知识
很好的东东
帖子不错,道声谢
想拜师学艺
我的呼喊

搜 索


用 户 登 录
用户名称:
登陆密码:
密码保存:

友 情 连 接

模板设计:部落窝模板世界

blog名称:玻璃杯中的花生壳
日志总数:162
评论数量:249
留言数量:1
访问次数:828977
建立时间:2004年11月4日
 
 
 
[java]Java.lang.reflect包介绍
[ 2006/8/18 10:42:12 | By: 玻璃杯中的花生壳 ]
 
特此声明这些资料的原始内容来自www.java.sun.com,本人只是对其内容在个人的理解的基础上,进行翻译和整理。 一.概述        Reflection API可以使JAVA代码动态的查询和操作正在运行的JAVA类或者接口。Reflection 包含许多的类,例如Method类,该类可以在java.lang.reflect包中找到。 使用Reflection 中的类需要三个步骤: 1.获取一个要操作的类的对象,该对象属于java.lang.object包,该对象代表一个正在运行的一个类或接口。下面的三个方法是常用的获取类对象的方法: (1) Class c=Class.forname(“java.lang.String”); 使用.forname方法加载一个类,这里是字符串类,从而获得一个与该类对应的类对象。 (2) Class c=int.class; (3) Class c=Integer.TYPE; 2.获取要操纵的类对象的已经声明的方法 获取类对象的方法的最简单和常用的方法是getDeclareMethods()方法。该方法返回类对象中声明过的所有方法的一个方法数组(Method[])。还有其他的方法,在后面会有所介绍。 3.利用Reflection API操作类。 二.Java.lang.reflect包介绍 java.lang.reflect包中包含有两个接口,八个类。 InvocationHandler接口: Member接口:该接口可以获取有关类成员(域或者方法)后者构造函数的信息。 AccessibleObject类:该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。 Array类:该类提供动态地生成和访问JAVA数组的方法。 Constructor类:提供一个类的构造函数的信息以及访问类的构造函数的接口。 Field类:提供一个类的域的信息以及访问类的域的接口。 Method类:提供一个类的方法的信息以及访问类的方法的接口。 Modifier类: Proxy类:提供动态地生成代理类和类实例的静态方法。 ReflectionPermission类: 三.示例与说明 3.1 查找类中声明过的所有方法 import java.lang.reflect.*;    public class method1 {       private int f1(        Object p, int x) throws NullPointerException       {          if (p == null)             throw new NullPointerException();          return x;       }                public static void main(String args[])       {          try {            Class cls = Class.forName("method1");                      Method methlist[]               = cls.getDeclaredMethods();             for (int i = 0; i < methlist.length;                i++) {                  Method m = methlist[i];                System.out.println("name                  = " + m.getName());                System.out.println("decl class = " +                               m.getDeclaringClass());                Class pvec[] = m.getParameterTypes();                for (int j = 0; j < pvec.length; j++)                   System.out.println("                    param #" + j + " " + pvec[j]);                Class evec[] = m.getExceptionTypes();                for (int j = 0; j < evec.length; j++)                   System.out.println("exc #" + j                     + " " + evec[j]);                System.out.println("return type = " +                                   m.getReturnType());                System.out.println("-----");             }          }          catch (Throwable e) {             System.err.println(e);          }       }    } 代码说明: Class cls = Class.forName("method1");获取一个method1类的类对象cls。 Method methlist[]  = cls.getDeclaredMethods();返回一个类声明的所有方法的方法数组。 m.getDeclaringClass();返回声明该方法的类的实例。返回值为一个class。 m.getName():返回该方法的名字,返回值为字符串类型。 Class pvec[] = m.getParameterTypes():返回该方法的参数的类型的一个数组。注意参数的返回顺序是与方法声明时的顺序是相同的。 Class evec[] = m.getExceptionTypes():获取该方法抛出的例外的一个类型数组。 m.getReturnType():返回该方法的返回值的类型。返回值是一个class。        除了上述的Method类的方法外,还有别的方法。其中比较重要的有: Object invoke(Object obj,Object[] args)方法:对该方法进行实际的调用并执行。其中的两个参数的含义分别是调用该方法的一个类实例对象,和调用该方法的参数对象数组。具体如何应用请参看3.4节。 3.2 获取构造函数信息 import java.lang.reflect.*;             public class constructor1 {       public constructor1()       {       }                protected constructor1(int i, double d)       {       }                public static void main(String args[])       {          try {            Class cls = Class.forName("constructor1");                     Constructor ctorlist[]                = cls.getDeclaredConstructors();          for (int i = 0; i < ctorlist.length; i++) {                Constructor ct = ctorlist[i];                System.out.println("name                  = " + ct.getName());                System.out.println("decl class = " +                             ct.getDeclaringClass());                Class pvec[] = ct.getParameterTypes();                for (int j = 0; j < pvec.length; j++)                   System.out.println("param #"                      + j + " " + pvec[j]);                Class evec[] = ct.getExceptionTypes();                for (int j = 0; j < evec.length; j++)                   System.out.println(                     "exc #" + j + " " + evec[j]);                System.out.println("-----");             }           }           catch (Throwable e) {              System.err.println(e);           }       }    } Constructor ctorlist[] = cls.getDeclaredConstructors():获取该实例对象声明的所有的构造函数数组。 ct.getName():获取该构造函数的名称,返回值是一个字符串类型的变量。 ct.getDeclaringClass():返回声明该构造函数的类。返回值是一个class。 Class pvec[] = ct.getParameterTypes():返回该构造函数的参数的一个类型数组。返回的是一个class类型的数组。 Class evec[] = ct.getExceptionTypes():返回一个该构造函数的抛出的例外的一个类型数组。 除了上述的方法外,对于Constructor类还有一个很重要的方法: Object newInstance(Object iniargs[]):实际调用该构造函数并且生成一个实例对象。具体的应用参看3.5节。 3.3 获取类中域的信息 import java.lang.reflect.*;             public class field1 {       private double d;       public static final int i = 37;       String s = "testing";                public static void main(String args[])       {          try {             Class cls = Class.forName("field1");                      Field fieldlist[]               = cls.getDeclaredFields();             for (int i               = 0; i < fieldlist.length; i++) {                Field fld = fieldlist[i];                System.out.println("name                   = " + fld.getName());                System.out.println("decl class = " +                            fld.getDeclaringClass());                System.out.println("type                   = " + fld.getType());                int mod = fld.getModifiers();                System.out.println("modifiers = " +                           Modifier.toString(mod));                System.out.println("-----");             }           }           catch (Throwable e) {              System.err.println(e);           }        }    } 3.4 通过方法名调用方法 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);          }       }    }        我们会仔细地介绍方法调用的实现。 首先,声明了一个类method2,该类有一个方法public int add(int a, int b)。请注意该方法的方法名’add’、两个形式参数的数据类型int以及返回值类型int。因为,这些信息对动态地调用一个类的方法是非常重要的。        接下来在主调函数中实现的功能如下: 1.Class cls = Class.forName("method2"):获取类实例对象cls。 2.Class partypes[] = new Class[2];    partypes[0] = Integer.TYPE;    partypes[1] = Integer.TYPE; 声明一个类数组,用来保存两个参数的数据类型。 3.Method meth = cls.getMethod("add", partypes);注意getMethod方法,该方法将返回一个匹配的方法。匹配的条件,有两部分来限定。一个是方法名,一个是方法的参数类型数组。 (因为JAVA中允许方法的重载,所以必须说明参数的数据类型)参数类型数组中的各个参数类型的顺序必须与方法声明时的顺序相同。 4.method2 methobj = new method2():声明一个类method2的实例变量。 5.Object arglist[] = new Object[2];    arglist[0] = new Integer(37);    arglist[1] = new Integer(47); 声明一个对象数组,来存储两个参数实例。 6.Object retobj  = meth.invoke(methobj, arglist):实际调用add函数。注意方法invoke()的两个参数,methobj是调用方法(或者是声明方法)的类的一个实例, arglist确实被调用方法(这里是add方法)的,参数实例数组。返回值仍然是一个对象的实例retobj。 7.Integer retval = (Integer)retobj;    System.out.println(retval.intValue());将返回的对象实例,进行类型转换,并输出。 3.5 生成一个新的实例 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);          }       }    } 这个例子说明了Constructor类的newInstancce()方法的使用。其具体的过程与3.4节中使用invoke()方法类似,不再多说了。
 

阅读全文(2900) | 回复(2) | 编辑 | 精华
 
 
回复:Java.lang.reflect包介绍
[ 2006/8/18 15:27:15 | By: 玻璃杯中的花生壳 ]
 
 Class cls = Class.forName("method1"); 注意method1前要加上包名
 

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 
 
回复:Java.lang.reflect包介绍
[ 2006/8/18 11:00:58 | By: 玻璃杯中的花生壳 ]
 
JDK 1.3以后,JAVA增加了动态代理类,使用代理类,你可以接管类的方法调用,可以让你在类的方法调用前后,增加功能,比如日志,性能测试,等等。 代理类主要使用java.lang.reflect包下的InvocationHandler接口和Proxy类。首先要实现 InvocationHandler接口,该接口有一个方法invoke,代理类通过这个方法调用真正的实现方法,在这个方法中,你可以加入日志输出,性 能测试等等的代码。 由于代理类只能代理接口,所以你的真正的实现类要抽出接口,然后通过Proxy类的静态方法newProxyInstance生成代理类,通过调用调用代理类的接口方法完成对代理类所代理的实现类的方法调用。下面的代码通过一个简单的代理类,实现在方法的前后输出日志。 public class MyProxyHandler implements InvocationHandler { private Object obj; public MyProxyHandler(Object obj) { this.obj = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { System.out.println(method.getName() + " start."); result = method.invoke(obj, args); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { System.out.println(method.getName() + " end."); } return result; } } public interface MyBusiness { public void helloWorld(); public String sayHello(String target); } public class MyBusinessImpl implements MyBusiness { public void helloWorld() { System.out.println("Hello world!"); } public String sayHello(String target) { return "Hello " + target + "!"; } } public class MyTestClass { public static void main(String[] args) { MyBusiness business = new MyBusinessImpl(); MyBusiness businessProxy = (MyBusiness) Proxy.newProxyInstance( business.getClass().getClassLoader(), business.getClass().getInterfaces(), new MyProxyHandler(business)); businessProxy.helloWorld(); System.out.println(businessProxy.sayHello("Mr. Pu")); } }
 
 
» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)
 
部落窝Blog模板世界部落窝Blog模板世界
站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.033 second(s), page refreshed 144786585 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号