JAVA动态访问类方法和属性

JAVA动态属性

2008-12-04 17:07:42|  分类: JAVA程序设计 |  标签: |字号 订阅

还是从例开始,比如有一个类HelloWorld,它用方法sayHello()打印Hello World。

HelloWorld.java

view plaincopy to clipboardprint?

  1. package com.test;   
  2.   
  3. public class HelloWorld {   
  4.     public void sayHello() {   
  5.         System.out.println("Hello World");   
  6.     }   
  7. }  

package com.test;public class HelloWorld {    public void sayHello() {        System.out.println("Hello World");    }}

一般通过以下方法对其进行调用:

view plaincopy to clipboardprint?

  1.         HelloWorld helloWorld = new HelloWorld();   
  2.         helloWorld.sayHello();  

        HelloWorld helloWorld = new HelloWorld();        helloWorld.sayHello();

但很多时候,我们需要用一种更灵活的方法去进行调用。比如,在配置文件里配置类的名称,然后在程序里自动调用。在调用方法的前后执行特定的操作等等。使用过JSF,Struts,或Spring的人对此一定不会陌生:JSF可以绑定页面元素与事件,Spring通过配置文件可以不必通过new语句而自动为对象等设置属性值等等。近年来,被广泛利用的DI,AOP等技术大都是利用了JAVA的动态属性。

下面我们对JAVA的动态属性做一个详细介绍。

首先,我们简单介绍一下JAVA语言里跟动态性有关的几个类和接口:

类或接口名说明
java.lang.Class它包含了类本身的结构信息(Constructor, Field, Method, Annotation等)与相应的操作方法
java.lang.reflect.AccessibleObjectField, Method, Constructor等类的基类,主要提供权限控制机制
java.lang.reflect.Method包含方法的结构信息与方法操作
java.lang.reflect.Field包含属性的结构信息与属性操作
java.lang.reflect.Constructor包含构造方法的结构信息与构造方法的操作
java.lang.annotation.Annotation接口。附加在类,属性,方法等上的注释信息
java.lang.reflect.Proxy动态代理功能的一个很重要的类。可以通过它与InvocationHandler实现动态代理功能。
java.lang.reflect.InvocationHandler动态代理功能的一个很重要的接口。它与Proxy一起实现动态代理功能。
Java 使用Reflection API从Java类取得Method,Field,Annotation等信息,可以存取这些信息或者执行取得的Method方法。这些API都处于java.lang.reflect包里,数量不多,使用起来也不太难。

类结构信息的取得与实例的生成

可以通过几种方法取得Class信息:

通过对象引用:

this.getClass();

obj.getClass();

通过类名引用:

比如:HelloWorld.class

通过Class.forName(String className)取得

比如:Class.forName("com.test.HelloWorld");

取得Class信息后,就可以执行各种操作了。

view plaincopy to clipboardprint?

  1.         try {   
  2.             Class helloWorldClass = Class.forName("com.test.HelloWorld");   
  3.             HelloWorld helloWorld = (HelloWorld)helloWorldClass.newInstance();   
  4.             helloWorld.sayHello();   
  5.         } catch (ClassNotFoundException e1) {   
  6.             //TODO   
  7.         } catch (InstantiationException e) {   
  8.             //TODO   
  9.         } catch (IllegalAccessException e) {   
  10.             //TODO   
  11.         }   

        try {            Class helloWorldClass = Class.forName("com.test.HelloWorld");            HelloWorld helloWorld = (HelloWorld)helloWorldClass.newInstance();            helloWorld.sayHello();        } catch (ClassNotFoundException e1) {            //TODO        } catch (InstantiationException e) {            //TODO        } catch (IllegalAccessException e) {            //TODO        }

Class.forName方法可以根据指定的类名得到Class对象。Class.newInstance()方法可以为Class生成实例。它们有几种使用方法,具体的使用方法这里就不详述了。

方法:Method的取得与执行

可以通过Class.getMethod或Class.getMethods取得方法信息,还可以通过Class.invoke方法直接执行取得的方法。

  1.     Method sayHelloMethod = HelloWorld.class.getMethod("sayHello", new Class[]{});   
  2.     sayHelloMethod.invoke(helloWorld, null);  

    Method sayHelloMethod = HelloWorld.class.getMethod("sayHello", new Class[]{});    sayHelloMethod.invoke(helloWorld, null);

Class.getMethod:根据方法名称和参数类型取得方法。第一个参数为方法名(String),第二个参数为方法的参数类型(Class []),无参数的时候,可以设置为null或者空Class[]。比如,某方法有2各参数,一个为String,一个为Integer,则第2各参数为new Class[]{String.class, Integer.class}。Class.getMethod只能取得public类型的Method,要取得所有类型的Method,可以用Class.getDeclaredMethod。

Method.invoke:执行方法。第一个参数为Method类型,第2个参数为需要传送给方法的参数值(Object[]),无参数的时候,可以设置为null。

Method.setAccessible:Method 父类AccessibleObject.setAccessible(boolean)可以设置方法等的访问权限。比如sayHelloMethod.invoke原则上只能执行非private方法,不过如果为private方法设置了setAccessible(true);同样可以执行此方法。

属性:Field的取得与属性值的设置与赋值(set/get)

Field跟Method基本上一样。可以通过Class.getField(fieldName),Class.getFields,Class.getDeclaredField,Class.getDeclaredFields等取得。同样可以通过Field.setAccessible方法重新设置访问权限。具体可以参考上面的Method部分的讲解,这里不做详述了。

上面介绍了利用Java的反射(reflect)功能存取Class,Method,Field等的基本方法。另外还可以取得附加在Class,Method,Field上的注释信息(Annotation)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值