刚好在复习重温Kotlin官方文档,本来想着写点高级函数啥的,但是看到委托模式就忍不住想和Java做对比,先写着记下来吧,记得之前看到过一篇讲Kotlin的协变逆变的文章,与Java的泛型上下限很类似,有空找找看再写。
简单的Java静态代理
总共有4个类,IPersion
是通用接口,Student
是IPersion
的一个实现类,StudentProxy
也是IPersion
的一个实现类,同时StudentProxy
持有IPersion
接口对象,在实现接口方法的时候调用接口对象的相应方法实现了对具体类的代理处理,在代理类中可以进行一些通用操作,如在每个方法执行前后记录日志什么的。但是一个代理类只能代理一种类型的对象显然胜任不了复杂项目,于是乎动态代理就出现了。
1 | package DerivedModel; |
JDK动态代理
与静态代理相比,我们保留了Student
和IPersion
,并且新增了具体方法执行者DynamicHandler
,新增了获取被代理对象的工厂类DynamicFactory
。熟悉反射的同学一眼就看出来DynamicFactory
通过反射获取被代理对象,通过DynamicHandler
调用对应的反射方法,是的没错,确实如此,由于DynamicHandler
是具体方法的调用类,所以一些通用操作可以放在method.invoke()
方法执行前后。
1 | package DerivedModel; |
cglib动态代理
cglib代理和JDK动态代理很类似,只不过cglib依赖了ASM快速生成被代理对象的字节码
1 | package DerivedModel; |
Kotlin的静态代理-委托模式
委托模式已经证明是实现继承的一个很好的替代方式, 而 Kotlin 可以零样板代码地原生支持它。下面DerivedProxy
的超类型列表中的 by
-子句表示person
将会在DerivedProxy
中内部存储, 并且编译器将生成转发给person
的所有IPersion
的方法。
1 | package DerivedModel |
执行结果如下:
1 | My name is 邹小雨 ,I'm eating |
如果在代理类中重写了对应被代理类的属性和方法呢?我们试试
1 | package DerivedModel |
执行结果如下:
1 | My name is Proxy ,I'm eating food that belongs to her |
属性委托
到这里已经和题目相关性不大了,部分事项已经写到注释里啦,请以官方文档为准哦~
1 | package DerivedModel |
执行结果如下:
1 | DerivedModel.ValueTest@3b81a1bc,thank you for delegating name to me! |
v1.5.2