15.15.3 使用动态代理来实现混型

可以使用动态代理来实现混型,通过使用动态代理,所产生的类型将会是已经混入的组合类型。

由于是使用的jdk的动态代理,所有必须实现接口

class ProxyMixin implements InvocationHandler {
    //map集合,记录所有的方法名称和对象
    Map<String,Object> delegatesByMethod;
    public ProxyMixin(TwoTuple<Object,Class<?>>... pairs){
        //初始化map对象
        delegatesByMethod = new HashMap<>();
        //TwoTuple 里面可以放两个参数,分别是,对象和接口类的class
        //对可变参数进行循环
       for(TwoTuple<Object,Class<?>> pair:pairs){
           //使用接口获取接口所对应的所有方法,对所有方法进行循环
           for(Method method:pair.second.getMethods()){
               String methodName = method.getName();
               //如果方法名不存在,就把方法名和对象一起添加进去
               if(!delegatesByMethod.containsKey(methodName))
                   delegatesByMethod.put(methodName,pair.first);
           }
       }
    }

    /**
     *
     * 动态代理的对方法的拦截方式
     *
     * @param proxy 代理对象
     * @param method    方法
     * @param args  参数
     * @return 返回执行结果
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        //从map中找到当前方法名,获取其实现对象
        Object delegate = delegatesByMethod.get(methodName);
        //用实现对象 执行当前方法,返回结果
        return method.invoke(delegate,args);
    }

    /**
     * 生成对象
     *
     * @param pairs 可变参数列表
     * @return  返回代理对象
     */
    public static Object newInstance(TwoTuple<Object,Class<?>>... pairs){
        //获取下挂接口
        Class[] interfaces = new Class[pairs.length];
        for(int i = 0;i<interfaces.length;i++) interfaces[i] = pairs[i].second;
        //获取类加载器
        ClassLoader c1 =  ClassLoader.getSystemClassLoader();
        //创建代理对象
        return newProxyInstance(c1,interfaces,new ProxyMixin(pairs));
    }


}

/**
 * 测试
 */
public class DynamicProxyMixin {
    public static void main(String[] args) {

        Object mixin = ProxyMixin.newInstance(tuple(new BasicImp(),Basic.class),
                tuple(new TimeStampedImpl(),TimeStamped.class),
                tuple(new SerialNumberedImpl(), SerialNumbered.class)
                );
        Basic b =(Basic) mixin;
        TimeStamped t = (TimeStamped) mixin;
        SerialNumbered s = (SerialNumbered) mixin;
        b.set("Hello");
        System.out.println(b.get());
        System.out.println(t.getStamp());
        System.out.println(s.getSerialNumber());

    }
    private static <A,B> TwoTuple<A,B> tuple(A a,B b){
        return new TwoTuple(a,b);
    }
}
Hello
1531066404027
1

测试类混合了三种类的能力

辅助类:

public class TwoTuple<A,B> {
    public final A first;
    public final B second;

    public TwoTuple(A a,B b){
        first = a;
        second = b;
    }

    public String toString(){
        return "(" + first + ", " + second + ")";
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值