JAVA反射机制
一、Java反射机制的概念




1 package cn.happy.reflet.classinfo; 2 3 public class Person { 4 private String name; 5 private String gender; 6 private int age; 7 8 9 private String getName() { 10 return name; 11 } 12 private void setName(String name) { 13 this.name = name; 14 } 15 public String getGender() { 16 return gender; 17 } 18 public void setGender(String gender) { 19 this.gender = gender; 20 } 21 public int getAge() { 22 return age; 23 } 24 public void setAge(int age) { 25 this.age = age; 26 } 27 public String toString() { 28 return "Person [name=" + name + ", gender=" + gender + ", age=" + age 29 + "]"; 30 } 31 32 }

1 package cn.happy.reflet.classinfo; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Method; 5 6 import javax.swing.JOptionPane; 7 8 public class ReflectDemo { 9 /** 10 * 构造函数 11 * */ 12 public ReflectDemo(){ 13 //用户输入类的全路径() 14 String classpath=JOptionPane.showInputDialog(null,""); 15 try { 16 //利用class.forName()获得Class类的实例,寻找全路径 并将该类返回 17 //根据类的全路径进行类加载,返回该类的class对象 18 Class cla=Class.forName(classpath); 19 //利用class对象cla的自审,返回方法对象集合 20 Method[] method=cla.getDeclaredMethods(); 21 //遍历method数组,并输出方法信息 22 System.out.println("*************获取方法信息************"); 23 for (Method meth : method) { 24 System.out.println(meth.toString()); 25 } 26 System.out.println("*************获取方法信息结束************"); 27 28 //利用class对象cla的自审,返回成员属性对象集合 29 Field[] fileds=cla.getDeclaredFields(); 30 31 System.out.println("*********获取属性的信息************"); 32 for (Field field : fileds) { 33 System.out.println(field.toString()); 34 } 35 System.out.println("*********获取属性的信息************"); 36 } catch (ClassNotFoundException e) { 37 e.printStackTrace(); 38 } 39 } 40 41 /** 42 *1.获取访问类的class对象 43 *2.调用class对象的方法返回访问类的方法和属性信息 44 * */ 45 }

1 package cn.happy.reflet.classinfo; 2 3 public class TestReflect { 4 //如何使用javaApi获取类的属性的步骤 5 public static void main(String[] args) { 6 ReflectDemo rd=new ReflectDemo(); 7 8 } 9 }



创建对象
上面三个对象都在java.lang.reflect包下,都实现了java.lang.reflect.Member接口
可以通过Constructor对象来调用相应的构造方法创建对象
通过Field对象直接访问并修改对象的属性值
如何通过反射创建对象
1.使用newInstance()创建对象
2.使用Constructor对象创建对象
实际上,只有当程序需要动态创建某个类的对象是才会考虑到使用反射,通常在开发通用性比较广的框架、基础平台时可能会大量使用反射,因为在很多Java EE框架中都需要根据配置文件信息来创建Java对象,从 配置文件读取的只是某个类的字符串类名,程序想根据字符串来创建对应的实例,就必须使用反射,如我们所知道的Spring框架就应用了这个技术
反射技术多用于框架即基础平台中
使用Constructor()创建对象
如果我们不想利用默认构造方法来创建java对象,而想利用指定的构造方法来创建java对象,则需要利用Constructor对象了,每个Constructor对应一个构造方法,利用指定构造方法来创建java对象需要三个步骤:
1.获取该类的Class对象
2.利用Class对象的getConstructor()方法来获取指定构造方法
3.调用Constructor的newInstance()方法来创建java对象
如何使用反射调用方法:
实例:
在调用方法时如何传参数
如果我们把Person类的setName方法的访问权限设为私有,这时再运行程序,则会抛出NoSuchMethodexception异常,这时因为当通过Method的invoke()方法调用对应的方法时
java会要求程序必须有调用该方法的权限,如果程序确实需要调用某个对象的private方法,可以先调用setAccessible(Boolean flag)方法,将Method对象的accessible标志设置为指示的布尔值,值为true则表示该Method在使用时用该取消java语言的访问权限检查,值为false则表示该Method在使用时应该实施java语言访问权限检查
如何访问属性
File.setAccessible(true);
我们对获取到的私有属性调用方法setAccessible(true),便可以使用这两个方法随意的访问指定对象的所有属性,包括private访问控制属性
访问Person类中的属性
通过反射获取Person类中的属性
事实上在实际开发中,我们没有必要使用反射,来访问已知类的方法和属性,只有当程序需要动态创建某个类的对象的时候我们才会考虑使用反射,例如,我们要从配置文件中读取以字符串形式表示的类时,我们就要使用反射来获取他的方法和属性了,
又比如,我们可以使用反射来写一个,在Action中接受参数的公共方法,这样不同的Action在接收参数时,只需要调用接收参数的公共方法就可以了,而不必每次都为没一个参数写一句request.getParameter语句了
动态创建和访问数组
在java.lang.reflect包下还提供了一个Array类,Array对象可以代表所有的数组,程序可以通过使用Array来动态的创建数组,并且操作数组的元素
Array类提供了如下几类方法:
1.通过newInstance() 方法我们可以创建一个具有指定的元素类型、指定唯独的数组
2.getXxx()方法,将返回Array数组中的第index个元素,这与使用反射返回属性类似
3.
下面实例如何使用这些方法来动态的创建和访问数组
只用三行代码就完成了动态创建数组及访问数组
使用Array类来创建多维数组
总结:
在反射机制概述中,我们了解到了java的一个动态特性:反射 知道了反射机制是一种动态获取信息以及动态调用对象方法的功能,通过反射我们可以在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,判断任意一个类所具有的方法和属性,同时,也可以在运行时调用任意一个对象的方法以及生成动态代理,如果编译时我们根本无法预知该对象或类可能属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,那么此时我们就必须使用反射,事实上,在我们平时写代码的时候反射技术用的并不是很多,因为通过反射创建对象时性能要稍微低一些,只有当程序需要动态创建某个类的对象时才会使用反射Class类是反射的核心类,