初识JAVA反射<一>_0626
反射
一.最开始接触javaSE的时候就没有怎么学过反射,感觉好难,老师讲的也很晦涩,然后就没有然后了,最近项目中用到了AOP切面编程,全都是运用的反射,不学不行了,索性问问过来人。
1.一种说法是java反射实际上就是转换,讲java代码转换为二进制。
2.第二种说法就是将javaBean什么的转换成你需要的形式。
现在给我的想法,我觉得在SpingMVC上就用到了反射,我前台的ajax传过来的值,可以直接传到我的Controller的参数中得类,比如说,
$.ajax{
....
data:{deptCode:deptCode,
deptName:deptName
}
}
public void getDeptController(HttpsevletRequest req,Dept dept){
}
public class Dept{
private String deptCode;
private String deptName;
.....getter///setter///省略了
}
类似这样的一个例子,我自认为就是运用的反射,将穿过来的值,转换到javaBean当中去,然而具体的源代码我没有看过,还是觉得殊途同归,然后经过园子里的一位高人,在他的基础上,我改造了一下,算是初探java反射吧:
Java 反射机制是指Java程序可以在执行期载入,探知,使用编译期间完全未知的classes.这句话可能有点难以理解,我们可以通过一个例子来看。在Java程序中我们经常会用到这样一条语句来创建一个对象。Date date = new Date();在这条语句中date的类型(Java.util.Date)在编译时 已经确定。那么,有没有办法使我们把对象类型的确定时间由编译转到运行,答案是肯定的。这就是Java反射机制所提供的便利。而且它不单单可以生成对象还可以获取Field,对Field设值,及调用方法等。
谈及Java反射机制就一定要知道一个名为“Class”的类,它是Java反射机制的基础。“Class”和其它类一样继承于Object类,它的实例对象用来描述Java运行时的一种类型,接口,或者原始类型(比如int).“Class”的实例要由JVM创建,它没有公用的构造方法。下面我们来看一下如何获得"Class"类实例。
主要有三种方法。
一,通过Class类的静态方法forName获取。Class cla = Class.forName("java.lang.String");
二,通过.Type或.class属性获得。Class cla = String.class;Class cla1 = int.Type;
三,通过实例变量的getClass方法获得。String s = ""; Class cla = s.getClass();
如上所示实例对象cla就是对String类型的描述,通过它我们就可以创建一个String实例,并调用其中的方法。下一篇我将通过一个例子来展示如何使用Java反射机制。
JAVA反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
下面我以顾客买相机为例来说明Java反射机制的应用。例子中涉及的类和接口有:
Camera接口:定义了takePhoto()方法。
Camera01类:一种照相机的类型,实现Camera接口。
Camera02类:另一种照相机的类型,实现Camera接口。
Seller类:卖照相机。
Customer类:买相机,有main方法。
(转自http://www.cnblogs.com/ksyou/archive/2009/03/21/1418279.html)
具体的实现我还是上我自己的吧:
1 package com.zxd.June_26; 2 3 public interface Camera { 4 public void takePhoto(); 5 } 6 7 8 9 package com.zxd.June_26; 10 11 public class Camera01 implements Camera{ 12 private int prefix = 300; 13 private String zoom = "10times"; 14 public void takePhoto() { 15 System.out.println("Camera01 takes a photo!!"); 16 } 17 18 19 public void takeVidio(){ 20 System.out.println("Camera01 takes a video!!"); 21 } 22 23 } 24 25 26 27 package com.zxd.June_26; 28 29 public class Customer { 30 31 public static void main(String[] args) throws Exception{ 32 33 Seller seller = new Seller(); 34 seller.getAttr("com.zxd.June_26.Camera01"); 35 36 seller.getMethod("com.zxd.June_26.Camera01"); 37 38 seller.testFunction("com.zxd.June_26.Camera01"); 39 } 40 41 } 42 43 44 45 package com.zxd.June_26; 46 47 import java.lang.reflect.Field; 48 import java.lang.reflect.Method; 49 50 public class Seller { 51 52 53 public void getAttr(String args) throws Exception{ 54 Class cla = Class.forName(args); 55 Object obj = cla.newInstance(); 56 Field[] field = obj.getClass().getDeclaredFields(); 57 58 for(int i = 0; i < field.length; i++){ 59 field[i].setAccessible(true); 60 System.out.println("第"+i+"个成员变量为:"+field[i].getName()+"="+field[i].get(obj)); 61 } 62 63 } 64 65 public void getMethod(String args) throws Exception{ 66 Class cls = Class.forName(args); 67 Object obj = cls.newInstance(); 68 Method[] method = obj.getClass().getDeclaredMethods(); 69 70 for(int i = 0; i < method.length; i++){ 71 System.out.println("第"+i+"个方法名为:"+method[i].getName() ); 72 } 73 } 74 75 public void testFunction(String args) throws Exception{ 76 Class cla = Class.forName(args); 77 Object obj = cla.newInstance(); 78 Method[] method = obj.getClass().getDeclaredMethods(); 79 80 for(int i = 0 ;i < method.length; i++){ 81 String methodName = method[i].getName(); 82 83 Method methodFunction = cla.getMethod(methodName, null); 84 // System.out.println(methodFunction.getName()); 85 System.out.print("遍历调用Camera的第"+i+"方法"); 86 methodFunction.invoke(obj, null); 87 // System.out.println(methodFunction.invoke(obj, null));; 88 } 89 } 90 91 92 }
测试结果为:
第0个成员变量为:prefix=300
第1个成员变量为:zoom=10times
第0个方法名为:takePhoto
第1个方法名为:takeVidio
遍历调用Camera的第0方法Camera01 takes a photo!!
遍历调用Camera的第1方法Camera01 takes a video!!
现在我还有一些问题,就是对于Method.invoke这个方法,请诸位等待我的第二个版本,我看看,在Method类下面有没有获得形参的方法,这样我就可以用invoke这个方法传递一些参数。