java基础巩固之反射(二)

    接上一部分,这里主要说三个部分,一个是关于反射的源头Class类,接下来是代理,一个是静态代理,一个是动态代理。基于反射机制的主要是动态代理,我自己对动态代理也不熟悉,所以这里也一并学习一下。

Class类:

     首先是说明java的运行机制:普通的类经过编译后生成.class文件。java虚拟机加载.class文件,之后该.class文件加载到内存后,就是一个运行时类,该运行时类就是一个Class实例。这里说明一下每个运行时类只加载一次,也就是说以下运行结果全部为真:

                 Class clazz1=Person.class;//第一种
		Person p=new Person();//第二种getClass
		Class clazz2=p.getClass();
		System.out.println(clazz2.getName());
		String classname="refection.Person";//第三种Class的静态方法获取,动态性
		Class clazz3=Class.forName(classname);
		System.out.println(clazz1==clazz2);
		System.out.println(clazz2==clazz3);
当然上面的代码也写出了获取Class实例的三种方式:第一四.class获取,第二种是getClass()函数获取,第三种是一种动态性的获取,就是通过类的名字字符串获取,给一个什么样的字符串获取他的Class,当然必须有这个类,不然抛异常。

特别说明,我们通过反射获取Class实例之后,可以做的一些事情,上一篇也说了很多任意,这里说一下大致的几种,很多方法上一篇都写到了,这里不再代码示例了。

         得到Class的实例之后,我们可以做以下事情:
*   1*创建对应的运行时对象(例如Person对象)
*   2可以获取该类的完整结构(属性,方法,构造器,父类等等)
*   3*调用对应的运行时类的结构(方法,属性,构造器等等)
*   4反射应用:动态代理

下面说说代理,这里代理的原理和两个概念我直接在尚硅谷的教学视频中截的图片。


静态代理:

    被代理类和代理类具有相同的父类(一般是接口),都要实现接口方法,而且代理类和接口基本上实现一对一的功能限定。一个新的接口就得重新设计代理类。

   这里的举例:富士康只能生产手机,我们提供一个手机生产的接口,其他手机厂商实现接口,富士康也要实现手机生产接口,这样富士康就能为手机代工。

  代码如下:

   

interface PhoneMake
{
	 /*
	  * 定义造手机方法
	  */
 	public void makephone();
}
 /*
  * 小米手机厂商
  */
 class MiPhoneMake implements PhoneMake
 {

	@Override
	public void makephone() {
		System.out.println("小米出了一批新手机");
	}
	 
 }
 /*
  * 富士康代工厂
  */
class FuShiKang implements PhoneMake
{
	/*
	 * 定义一个制造手机接口的对象
	 * 通过构造方法传入具体的被代理对象
	 * 实现控制被代理类的执行
	 */
	PhoneMake phone;
     public FuShiKang(PhoneMake phone)
     {
    	 this.phone=phone;
     }
	@Override
	public void makephone() {
		System.out.println("富士康开始赶工啦");
		phone.makephone();
	}
	}
public class ProxyPhone {

	public static void main(String[] args) {
     MiPhoneMake mi=new MiPhoneMake();//创建被代理对象
     FuShiKang fsk=new FuShiKang(mi);//创建代理类的对象
     fsk.makephone();
	}

}
   倘若让富士康生产衣服,这个代理肯定就得重写。如果类型多了,就更麻烦。所以引入动态代理。

 动态代理

  就是可以你给我什么样子的接口,我都能给你实现代理的这样一种类。

  直接上代码吧,注释写的非常详细:

//手机制造接口
interface PhoneMake
{
   public void makePhone();	
}
//手机制造被代理类
class iPhoneMake implements PhoneMake
{

	@Override
	public void makePhone() {
		System.out.println("iPhone10s要造出来啦");
	}
}
//动态代理类
class MyInvocationHandler implements InvocationHandler
{
    Object obj;
    /*
     * 这里定义一个函数
     * 1 实现对被代理的对象实例化
     * 2 返回一个代理类的对象
     * @return 中的三个参数,第一个是被代理类的ClassLoader,第二个是需要执行的接口,第三个是实现了InvocationHandler的对象
     */
    public Object initabc(Object obj)
    {
    	this.obj=obj;
    	return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this);
    	
    }
    /*
     * 通过代理类对象调用被代理类方法时,都会转入调用invoke方法
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object returnVale=method.invoke(obj, args);//调用被代理类
		return returnVale;
	}
}
public class ProxyTest {
    public static void main(String[] args)
    {
    	//代理手机
    	iPhoneMake iphone=new iPhoneMake();
    	MyInvocationHandler my=new MyInvocationHandler();
    	Object obj=my.initabc(iphone);
    	PhoneMake pst=(PhoneMake) obj;
    	pst.makePhone();
    	//鞋子代理
    	LiNingShoesMake lining=new LiNingShoesMake();
    	ShoesMake sho=(ShoesMake) my.initabc(lining);
    	sho.makeShoes();
    	
    }
}
//鞋子制造接口
interface ShoesMake
{
 public void makeShoes();	
}
//鞋子制造被代理类
class LiNingShoesMake implements ShoesMake
{
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void makeShoes() {
<span style="white-space:pre">		</span>System.out.println("李宁新款正在制造");
<span style="white-space:pre">		</span>
<span style="white-space:pre">	</span>}
}
  这里定义的动态代理,不仅可以代理手机生产,还可以代理衣服制造,通过代理类对被代理的对象方法进行调用,代理类会自动转打调用invoke方法,在这个方法里面调用被代理类的方法。这样应该比较容易理解了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值