浅谈Java反射机制

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 stub
		Customer 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.id
private java.lang.String Customer.name
private int Customer.age
private java.lang.String Customer.phone
private 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.getType
			Object 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 stub
		Customer 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:1
name:wangzhicheng
age:28
phone:13866916216
拷贝的对象是:
1 wangzhicheng 28 13866916216


 

五 反射也有副作用,影响程序的性能

六 更多参考资料:Java Reflection  in Action

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值