Java学习之反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
Java反射机制提供的功能
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
关于反射机制中的使用推荐博客:http://blog.csdn.net/xiaoxian8023/article/details/9206055
Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;
1 Class c = Class.forName("Triangle"); //获取Class对象 2 //获取相应参数的构造参数 3 Constructor con = c.getConstructor(long.class,long.class,long.class); 4 //通过相应的构造函数创建对象 5 Object obj = con.newInstance(testcase[0],testcase[1],testcase[2]); 6 //获取相应参数的方法 7 Method m = c.getDeclaredMethod("getType", c);
m.invoke(obj,obj);
关于获取方法的getDeclaredMethod和getMethod的区别
getDeclaredMethod可以获取私有的方法和保护的方法
getMethod只能获得public公有方法,如要访问私有方法,需设置可见性setAccessible(),设置为true就和getDeclaredMethod作用相同。
可是从类的开发要求而言,一直都强调类之中的属性必须封装,所以现在调用之前要想办法解除封装即setAccessible()
packagecn.mldn.demo; importjava.lang.reflect.Field; classPerson { privateString name; } publicclassTestDemo { publicstaticvoidmain(String[] args) throwsException { Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象 Object obj = cls.newInstance(); // 对象实例化属性才会分配空间 Field nameField = cls.getDeclaredField("name") ; // 找到name属性 nameField.setAccessible(true) ; // 解除封装了 nameField.set(obj, "张三") ; // Person对象.name = "张三" System.out.println(nameField.get(obj)); // Person对象.name } }
相关讨论可见http://www.zhihu.com/question/24304289
package test.reflection; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Person { private String name;//私有属性 public String address; public Person(String name){ this.name=name; } private void setAddress(String address){ //私有方法 this.address=address; } public static void main(String[] args) { try{ Person person=new Person("zhangsan"); Class<Person> cls=Person.class; //获得私有方法 Method method=cls.getDeclaredMethod("setAddress", new Class[]{String.class}); //设置私有方法可以被访问 method.setAccessible(true); //调用私有方法 method.invoke(person, new Object[]{"BJUT"}); System.out.println(person.address);//输出BJUT //访问私有变量 Field field=cls.getDeclaredField("name"); field.setAccessible(true); System.out.println(field.get(person));//输出zhangsan }catch(Exception ex){ ex.printStackTrace(); } } }
这种反射机制在框架开发的时候经常用到,比如简单工厂或抽象工厂时,为了降低耦合度,我们需要把用new创建的对象用反射来实现,这样就可以通过配置文件等来管理整个项目而不需要修改代码。