动态代理

  1. JDK动态代理中的问题——调用proxy的toString方法引起的栈溢出
  2. kotlin反射
  3. 示例
  4. Exception in thread “main” java.lang.IllegalArgumentException: wrong number of arguments
val ob: Any = method!!.invoke(obj, *(args ?: arrayOfNulls<Any>(0))) // 使用传播运算符达到和java多参数相同的效果
 
* 数组对象 :kotlin的spread 操作符,
* 解释:When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):

val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
动态反射主要是,使用接口调用接口方法去对应的实现类执行接口的方法
  1. 设置接口类
interface People {
    fun work(): String
}
  1. 实现接口
public class Student implements People {
    @NotNull
    @Override
    public String work() {
        Log.d("ls", "努力学习");
        return "学生的工作是学习";
    }
}

3.InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法

class WorkHandler(var obj: Any): InvocationHandler {

    var target: Any? = null
    fun newProxy(tar: Any): Any {
        target = tar
        return  Proxy.newProxyInstance(this.javaClass.classLoader, target?.javaClass?.interfaces, this)
    }

    /**
     * proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0
     * method:我们所要调用某个对象真实的方法的Method对象
     * args:指代代理对象方法传递的参数
     *
     * throws Throwable
     */
    override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
        return try {
            //在真实的对象执行之前我们可以添加自己的操作
            Log.d("ls", "before invoke。。。")
            // Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
            // 为什么Kotlin在使用代理时抛出IllegalArgumentException : https://stackoverflow.com/questions/41774450/why-is-kotlin-throw-illegalargumentexception-when-using-proxy
            val ob: Any = method!!.invoke(obj, *(args ?: arrayOfNulls<Any>(0))) // 使用传播运算符达到和java多参数相同的效果
            //在真实的对象执行之后我们可以添加自己的操作
            Log.d("ls", "after invoke。。。")
            ob
        } catch (t: Throwable) {
            t.message!!
        } finally {
            Log.d("ls", "执行完成")
        }
    }
}
  1. 测试
//要代理的真实对象
            val p: People = Student()
            //代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
            val handler: InvocationHandler = WorkHandler(p)
            /**
             * 通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数
             * 第一个参数:people.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象
             * 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
             * 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上
             */
            val proxy = Proxy.newProxyInstance(handler.javaClass.classLoader, p.javaClass.interfaces, handler) as People
            Log.d("ls", proxy.work())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值