一. 什么是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 method
setMethod.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;
}
}