Java反射

一.反射的含义。
   相信大家平时或多或少有了解到Java反射,但是什么是Java反射呢?
   在日常生活中我们通过镜子可以看到自己的映像,这个映像和我们不止和我们长得一样,动作什么也是相同的,而Java反射的API就像一面镜子,通过反射我们可以看到一个Java类的“映像”,意思就是说我们可以看到该Java类内部的结构,这个结构是运行时刻的内部结构,也就意味着Java反射是动态地获取信息和动态地调用对象的方法。
   知道了Java类内部的结构有什么用呢?对于一个类,我们无非就是创建该类的对象,然后调用这个对象中的方法。所以知道了Java类内部的结构之后,我们做的也是和上面相同的事,这种交互方式和直接使用源码的效果是一样的。不过反射API性能比较差,比直接使用慢了一,两个数量级,虽然在现在的JVM的实现中,反射操作的性能有了很大的提升,不过在实际使用中我们还是需要进行权衡,在适当的时机使用反射API。至于什么时候使用和为什么要使用反射,接下来我们一点一点了解。

二.基本用法。
    只要有了java.lang.Class的对象,我们分别通过 getConstructorgetFieldgetMethod方法就可以获取到该类的构造方法,域和方法;这三个方法还有相应的getDeclaredXXX版本,两类方法的区别在于getDeclaredXXX版本只获取该类自身所声明的元素,而不考虑继承的。

    简单实用:

public class Salary {
	private int mBaseSalary;
	public int mSalary;
	
	public Salary(int baseSalary) {
	   mBaseSalary = baseSalary;
	}
	
	public void payOff(int bonus) {
		mSalary = mBaseSalary + bonus;
	}
}
/**
		 * 一般做法
		 */
		Salary salary = new Salary(100);
		salary.payOff(50);
		System.out.println("Normal ->" + salary.mSalary);

		/**
		 * 使用反射
		 */
		try {
		  //获取构造方法
		  Constructor constructor = Salary.class.getConstructor(int.class);
		  //创建对象
		  Salary salaryReflect = (Salary)constructor.newInstance(1000);
		  //获取方法
		  Method method = Salary.class.getMethod("payOff", int.class);
		  //调用方法
		  method.invoke(salaryReflect, 500);
		  //获取域
		  Field field = Salary.class.getField("mSalary");
		  //获取域的值
		  System.out.println("Reflect ->" + field.getInt(salaryReflect));
		} catch (Exception e) {
			e.printStackTrace();
		}

运行结果:

Normal ->150
Reflect ->1500

三.实用场景。
·a 当某个类有多个版本,且每个版本所提供的方法名和参数不尽相同,而调用代码又必须与这些不用的版本都能协同工作,这时就可以通过反射API来依次检查实际的类中是否包含某个方法来选择性地使用。

·b  在有些情况下,可能需要从远端加载一个Java类来执行。比如一个客户端Java程序可以通过网络从服务器端下载Java类来执行,从而实现自动更新。当代码逻辑需要更新的时候,只需要部署一个新的Java类到服务器端即可。一般的做法是通过自定义类加载器下载了类字节代码之后,定义出 Class类的对象,再通过newInstance方法就可以创建出实例了。不过这种做法要求客户端和服务器端都具有某个接口的定义,从服务器端下载的是这个接口的实现。这样的话才能在客户端进行所需的类型转换,并通过接口来使用这个对象实例。如果希望客户端和服务器端采用更加松散的契约的话,使用反射API就可以了。两者之间的契约只需要在方法的名称和参数这个级别就足够了。服务器端Java类并不需要实现特定的接口,可以是一般的Java类。

·c 设计模式中的代理模式分为静态代理和动态代理,动态代理只需实现InvocationHandler接口并重写调用其方法invoke即可;看到“invoke”是否有点熟悉?没错,动态代理也是利用反射机制实现的。 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值