浅谈Java反射机制
一 从一个实例出发--在运行时获取某个对象相关信息
1. 我们首先定义一个Customer类,表示客户的相关信息
public class Customer {private Long id;private String name;private int age;private String phone;public Customer() {}public Customer(Long id,String name,int age,String phone) {this.id=id;this.name=name;this.age=age;this.phone=phone;}public final Long getId() {return id;}public void setId(Long id) {this.id=id;}public final String getName() {return name;}public final void setName(String name) {this.name=name;}public final int getAge() {return age;}public void setAge(int age) {this.age=age;}public final String getPhone() {return phone;}public void setAge(String phone) {this.phone=phone;}}
2. 现在我们写一个类,实现获取Customer实例所有的构造方法和普通方法及属性信息
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectionApplication {/** * @param args */public static void ShowObjectInfo(Object obj) throws Exception {Class c=obj.getClass();int i;System.out.println(obj.toString()+"所有的构造方法是:");Constructor [] cs=c.getConstructors();for(i=0;i<cs.length;i++) {System.out.println(cs[i].toString());}System.out.println(obj.toString()+"所有的声明的方法是:");Method [] methods=c.getDeclaredMethods();for(i=0;i<methods.length;i++) {System.out.println(methods[i].toString());}System.out.println(obj.toString()+"所有的声明的属性是:");Field[] fields=c.getDeclaredFields();for(i=0;i<fields.length;i++) {System.out.println(fields[i].toString());}}public static void main(String[] args) throws Exception {// TODO Auto-generated method stubCustomer customer=new Customer(001L,"wangzhicheng",28,"13866916216");ShowObjectInfo(customer);}}
3. 运行结果是:
Customer@1fb8ee3所有的构造方法是:public Customer()public Customer(java.lang.Long,java.lang.String,int,java.lang.String)Customer@1fb8ee3所有的声明的方法是:public void Customer.setId(java.lang.Long)public final int Customer.getAge()public void Customer.setAge(int)public void Customer.setAge(java.lang.String)public final java.lang.String Customer.getPhone()public final java.lang.String Customer.getName()public final java.lang.Long Customer.getId()public final void Customer.setName(java.lang.String)Customer@1fb8ee3所有的声明的属性是:private java.lang.Long Customer.idprivate java.lang.String Customer.nameprivate int Customer.ageprivate java.lang.String Customer.phoneprivate java.lang.String Customer.phone
二 什么是反射
从以上实例中可以看出,在Java运行环境中,对于任意一个类或对象,我们可以知道这个类或对象有哪些属性和方法。不仅如此,对于任意一个对象,我们可以在运行时,调用它的任意方法。这种动态获取类的信息及调用对象的方法就是Java的反射技术。
三 为什么会有反射的存在--从java.lang.Class类说起
Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,这个工作记录着每个对象所属的类,用来保存这些类型的信息是Class类。所以我们可以通过Class获取类的相关信息,正如上例所示。
四 反射技术的简单应用--运行时复制对象
import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Member;import java.lang.reflect.Method;public class CopyObject {/** * @param args */public static Object copy(Object source) throws Exception {Class<?>c=source.getClass(); //获取source类型对象Object obj=c.newInstance(); //获取source实例对象Field[] fields=c.getDeclaredFields(); //获取声明的属性for(int i=0;i<fields.length;i++) {Field field=fields[i];String fieldName=field.getName(); //获取每个属性String firstLetter=fieldName.substring(0,1).toUpperCase(); //将属性名首字母转化为大写String getMethodName="get"+firstLetter+fieldName.substring(1); //获取get方法名称String setMethodName="set"+firstLetter+fieldName.substring(1); //获取set方法名称Method getMethod=c.getMethod(getMethodName, new Class[]{}); //获取get方法Method setMethod=c.getMethod(setMethodName, new Class[]{field.getType()});//获取set方法,此方法的类型是field.getTypeObject value=getMethod.invoke(source, new Object[]{});//调用get方法System.out.println(fieldName+":"+value);setMethod.invoke(obj, new Object[]{value});//调用set方法}return obj;}public static void main(String[] args) throws Exception {// TODO Auto-generated method stubCustomer customer=new Customer(001L,"wangzhicheng",28,"13866916216");Customer customercopy=(Customer)copy(customer);System.out.println("拷贝的对象是:");System.out.println(customercopy.getId()+" "+customercopy.getName()+" "+customercopy.getAge()+" "+customercopy.getPhone());}}运行结果:
id:1name:wangzhichengage:28phone:13866916216拷贝的对象是:1 wangzhicheng 28 13866916216
五 反射也有副作用,影响程序的性能
六 更多参考资料:Java Reflection in Action