Java反射 - Java开发/数据分析
一. 什么是JAVA的反射机制
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。
换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
注意: JAVA中,无论生成某个类的多少个对象,这些对象都会对应于同一Class对象;
二. 基础要点
1. 获取Class对象的方式
a) 针对每一个对象实例.getCalss(),可以得到对应的Class.
b) Class.forName(String),String的写法:包名.类名.就会创建包名.类名对应的那个对象
它具有动态潜质,只要换一个包就可以了. 所以真正意义的想体现动态编程只能使用这个方法.
c) 对于基本类型:封装类.TYPE代表了对应的基本类型的Class对象.Integer.TYPE对应的是int的Class对象
注意:Integer.class 和 Integer.TYPE是不一样的;
d) 类.class。<第4种是通用的.>
2. 生成目标类的实例:通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
a.调用无参数的构造函数
1、调用类的Class对象的newInstance方法,该方法会调用对象的默认构造器. Class<?> classType = ExtendType.class; Object inst = classType.newInstance();
2、调用默认Constructor对象的newInstance方法 Class<?> classType = ExtendType.class; Constructor<?> constructor1 = classType.getConstructor(); Object inst = constructor1.newInstance();
b.调用带参数构造函数
1.调用带参数Constructor对象的newInstance方法 Constructor<?> constructor2 = classType.getDeclaredConstructor(new Class[]{int.class, String.class})); Object inst = constructor2.newInstance(new Object[]{1, "123"});
如果想通过类的带参数的构造方法生成对象只能用上文中的b)中的方法;(注意,因为有了参数,所以格式有稍微的变化);
3. 调用类的函数: 通过Class对象来反射获得Method或者Field的对象,分别调用各自的方法(调用Method的invoke方法/Filed对象的set等方法)
[参考这里]
http://www.cnblogs.com/dennisit/archive/2013/02/26/2933508.html
http://www.devdiv.com/java_-blog-30695-56830.html
[获取方法和属性,包括静态的] http://azrael6619.iteye.com/blog/429797
[Array类]http://wiki.jikexueyuan.com/project/java-reflection/java-list.html
一个辅助特定对象的例子:
package com.demo.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflectionCopyObject { public Object copyObject(Object obj) throws Exception { //get the Class object Class<?> classType = obj.getClass(); //Class<?> classType = Class.forName("com.demo.reflection.User"); //by the constructor with parameters Constructor con = classType.getConstructor(new Class[]{String.class, int.class}); //create target class Object objectClass = con.newInstance(new Object[]{"Mao",10}); Field[] fields = classType.getDeclaredFields(); for (Field field : fields) {String filedName = field.getName();String getMethodName = "get"+filedName.substring(0,1).toUpperCase()+filedName.substring(1);String setMethodName = "set"+filedName.substring(0,1).toUpperCase()+filedName.substring(1);Method getMethod = classType.getMethod(getMethodName, new Class[]{});Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});Object value = getMethod.invoke(obj, new Object[]{});//invoke the target Obj's methodsetMethod.invoke(objectClass, value); } return objectClass; } public static void main(String[] args) throws Exception {User user=new User("cain",20);User result= (User) new ReflectionCopyObject().copyObject(user);System.out.println("result object name is:"+result.getName()+", and age is :"+result.getAge()); } } package com.demo.reflection; public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) {this.age = age; }}