浅谈java的反射机制,只是有助于去理解这一机制。

首先,在了解java的反射的时候,我们应该先提出几个问题,

第一,什么是java的反射机制?

第二,java反射机制的功能是什么?

第三,为什么要用java的反射机制?

第四,java的反射机制是如何实现的,实现的过程是什么样子的?

通过这四个问题,我们一点点如了解java的反射机制。

第一个问题:

java的反射机制是在运行状态,对任意一个类,能够知道这个类的所有属性和方法,对任意一个对象都能够调用它的任意方法和属性。这种动态调获取信息以及动态调用对象的方法功能就是java语言的反射机制。或者说就是加载一个运行时才知道的类以及他的完整内部结构。举个小栗子。

package com.sohu.action;


public class TestModel {


	String name="我是成员变量!";
	/**
	 * 构造函数
	 */
	public TestModel(){
		System.out.println("----我是构造函数!----");
	}
	/**
	 * 静态代码块
	 */
	static{
		System.out.println("---我是静态代码块-----");
	}
	
	{
		System.out.println("----我是非静态代码块----");
	}
	public void method(){
		System.out.println("---我是局部方法---");
	}
}


编写测试类:

public class Test3 {


	public static void main(String[] args) {
		try {
			//测试类名.class
			Class testModel=TestModel.class;
			System.out.println("获取包名===>"+testModel.getPackage());
			System.out.println("获取类的全路径===>"+testModel.getName());
			System.out.println("获取类名===>"+testModel.getSimpleName());
			Method[] methods = testModel.getMethods();
			for(Method method:methods){
				System.out.println("===获取方法===="+method.getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


上面的输出如下:

获取包名===>package com.sohu.action
获取类的全路径===>com.sohu.action.TestModel
获取类名===>TestModel
===获取方法====method
===获取方法====wait
===获取方法====wait
===获取方法====wait
===获取方法====hashCode
===获取方法====getClass
===获取方法====equals
===获取方法====toString
===获取方法====notify
===获取方法====notifyAll


这里的(类名).class就是反射。这里获取Class对象,还有两种方法:new (类).getClass()和Class.forName("类的全路径"),这个以后再细说。

通过上面的例子,我们可以看出,java的反射机制是可以获取运行时才知的类的方法和属性,其他的测试大家可以自己去做一下。这里的
现在来看第二个问题:

java反射提供的功能:

1.在运行时判断任意一个对象所属的类;

2.在运行时构建任意一个类的对象;

3.在运行时判断任意一个类所具有的成员变量和方法;

4.在运行时调用任意一个对象的方法;

以上四个在参考上面的例子进行理解;要注意,这四个都是在运行时而不是编译时进行的,也就是说在运行时不知道哪个类,通过反射实现了我们想要的。
5.生成动态代理。

然后我们来看,为什么要用反射机制;

首先,java的反射可以使代码更加灵活,更加容易实现面向对象。

期次就是java反射可以解藕。

对于最后一个问题,也还是浅显的用例子来说明一下,对于java的反射机制也只能起到一定理解作用,在深入还需要更加努力的去了解。

例如有这样的情况,我们有多个实体类,每个实体类中的属性都不一样,不会重复,我们要获取其中的某些属性,这些属性不在同一个实体类中,该如何去实现。直接上代码

package com.sohu.action;

import java.lang.reflect.Method;
import java.util.List;


/**
 * 封装联合实体类的方法
 * 利用java的反射类method
 * @author HBL1
 *
 */
public class ModelUtils {
	
	//需要一个List放置实体类
	List<Object> list=null;
	
	
	/**
	 * 构造函数,进行赋值
	 * @param list
	 */
	public ModelUtils(List<Object> list){
		this.list=list;
	}

	/**
	 * 获取属性的值
	 * @param fName  获取联合实体类的属性的名称
	 * @return
	 */
	public <T> T getValue(String fName){
		//组装方法名,这步是为了在调用此方法时直接进行参数传递就行,不需要传方法名称
		String methodName="get"+fName.substring(0,1).toUpperCase()+fName.substring(1);
		//获取方法名所在的实体类
		for(Object o:list){
			try {
				//查找方法,查找还有一个无参数的方法,单能传方法就尽量传,提高反射效率
				Method method = o.getClass().getMethod(methodName);
				//判断方法是否存在
				if(method!=null){
					//由于invoke返回的是Object类型,因此要强制转换成T类型
					return (T)method.invoke(o);
				}				
			} catch (Exception e) {
			}
		}
		return null;
	}

	public <T> void setValue(String fName,T value,Class<T> type){
		String methodName="set"+fName.substring(0,1).toUpperCase()+fName.substring(1);
		for(Object o:list){
			try {
				//查找方法
				Method method = o.getClass().getMethod(methodName,type);
				if(method!=null){
					method.invoke(o, value);
					return;
				}
			} catch (Exception e) {
			}
		}
	}
}
然后我们测试一下利用反射封装的类如何实现我们想要的,在这里实体类就不上传了。

package com.sohu.action;

import java.util.ArrayList;
import java.util.List;

import utils.system;
import flex.cc.baseInfo.model.GBankaccount;
import flex.cc.baseInfo.model.GInsurer;

public class Test2 {

	public static void main(String[] args) {
		List<Object> list =new ArrayList<Object>();
		list.add(new GBankaccount());
		list.add(new GInsurer());
		FieldsUtils fieldsUtils=new FieldsUtils(list);
		String name="fparentid";//这个是你要获取的属性值
		String value="我是测试数据";
		fieldsUtils.setValue(name, value);
		System.out.println(fieldsUtils.getValue(name));
	}
}

打印的结果如下:

我是测试数据
获取到了我们想要的数据。

对于java反射还在进一步理解中,有许多不足之处还请多指教,








  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值