Java语言的动态属性总结
- 格式:docx
- 大小:25.43 KB
- 文档页数:4
开篇:
还是从例开始,比如有一个类HelloWorld,它用方法sayHello()打印Hello World。
HelloWorld.java
< src="images/code/js/shCore.js" type="text/javascript"> < type="text/javascript"> < src="images/code/js/shBrushJava.js" type="text/javascript">
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.}
一般通过以下方法对其进行调用:
view plaincopy to clipboardprint?
1. HelloWorld helloWorld = new HelloWorld();
2. helloWorld.sayHello();
但很多时候,我们需要用一种更灵活的方法去进行调用。
比如,在配置文件里配置类的名称,然后在程序里自动调用。
在调用方法的前后执行特定的操作等等。
使用过JSF,Struts,或Spring 的人对此一定不会陌生:JSF可以绑定页面元素与事件,Spring通过配置文件可以不必通过ne w语句而自动为对象等设置属性值等等。
近年来,被广泛利用的DI,AOP等技术大都是利用了JAVA的动态属性。
下面我们对JAVA的动态属性做一个详细介绍。
首先,我们简单介绍一下JAVA语言里跟动态性有关的几个类和接口:
类或接口名说明
ng.Class 它包含了类本身的结构信息(Constructor, Field, Method, Annotation等)与相应的操作方法
ng.reflect.AccessibleObject
Field, Method, Constructor等类的基类,主要提供权限控制
机制
ng.reflect.Method包含方法的结构信息与方法操作
ng.reflect.Field包含属性的结构信息与属性操作
ng.reflect.Constructor包含构造方法的结构信息与构造方法的操作ng.annotation.Annotation接口。
附加在类,属性,方法等上的注释信息
ng.reflect.Proxy 动态代理功能的一个很重要的类。
可以通过它与InvocationHandler实现动态代理功能。
ng.reflect.InvocationHandler
动态代理功能的一个很重要的接口。
它与Proxy一起实现动
态代理功能。
Java 使用Reflection API从Java类取得Method,Field,Annotation等信息,可以存取这些信息或者执行取得的Method方法。
这些API都处于ng.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. }
Class.forName方法可以根据指定的类名得到Class对象。
Class.newInstance()方法可以为Class 生成实例。
它们有几种使用方法,具体的使用方法这里就不详述了。
方法:Method的取得与执行
可以通过Class.getMethod或Class.getMethods取得方法信息,还可以通过Class.invoke方法直接执行取得的方法。
view plaincopy to clipboardprint?
1. Method sayHelloMethod = HelloWorld.class.getMethod("sayHello", new Class[]{});
2. sayHelloMethod.invoke(helloWorld, null);
Class.getMethod:根据方法名称和参数类型取得方法。
第一个参数为方法名(String),第二个参数为方法的参数类型(Class []),无参数的时候,可以设置为null或者空Class[]。
比如,某
方法有2各参数,一个为String,一个为Integer,则第2各参数为new Class[]{String.class, I nteger.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.getD eclaredField,Class.getDeclaredFields等取得。
同样可以通过Field.setAccessible方法重新设置访问权限。
具体可以参考上面的Method部分的讲解,这里不做详述了。
上面介绍了利用Java的反射(reflect)功能存取Class,Method,Field等的基本方法。
另外还可以取得附加在Class,Method,Field上的注释信息(Annotation)。
有关注释(Annotation)的详细解说请参考:
Java Annotation之介绍篇(1)
Java Annotation之自定义篇(2)
Java Annotation之应用篇–运行期动态解析annotation (3)。