zoukankan      html  css  js  c++  java
  • 【Java SE】动态代理+空对象的实现

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class NullRobot {
        public static void main(String[] args) {
            //1
            Robot r = newNullRobot();
            if(Null.class.isInstance(r)){
    //        if(r instanceof Null){ //another way
                System.out.println("[NullRobot]");
            }
            System.out.println(r.name());
            List<Oper> l = r.ops();
            for (Oper oper : l) {
                System.out.println(oper.comm());
            }
            
            //2
            Robot r2 = (Robot) new NullRobotProxyHandler().bind(null);
            if(Null.class.isInstance(r2)){
                System.out.println("[NullRobot]");
            }
            System.out.println(r2.name());
            List<Oper> l2 = r2.ops();
            for (Oper oper : l2) {
                System.out.println(oper.comm());
            }
        }
        
        public static Robot newNullRobot(){
            return (Robot) Proxy.newProxyInstance(
                    NullRobot.class.getClassLoader(), //classLoader可以传入哪些?满足什么条件的classLoader可以被用来加载代理类
                    new Class[]{Robot.class, Null.class}, 
                    new NullRobotProxyHandler());
        }
    }
    
    interface Null{}
    
    class NullRobotProxyHandler implements InvocationHandler{
    
    //    Robot proxied = 
        class NRobot implements Robot
        , Null //事实上,可以不继承Null接口,而只要Proxy.newProxyInstance()中的Class[]包含Null.class即可使instanceof判断为true
        {
            private String name = "NoneName";
            @Override
            public String name() {
                // TODO Auto-generated method stub
                return name;
            }
            @Override
            public List<Oper> ops() {
                // TODO Auto-generated method stub
                return Collections.emptyList();
            }
        }
        
        //===another bind way binding real obj with proxy
        public Object bind(Object realObj){
            realObj = new NRobot();
            return (Robot) Proxy.newProxyInstance(
                    realObj.getClass().getClassLoader(), 
                    realObj.getClass().getInterfaces(), 
                    this);
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // TODO Auto-generated method stub
            return method.invoke(new NRobot(), args);
        }
        
    }
    
    interface Oper{
        String comm();
    }
    interface Robot{
        String name();
        List<Oper> ops();
    }
    class SnowRobot implements Robot{
    
        private String name ;
        public SnowRobot(String name){
            this.name = name;
        }
        @Override
        public String name() {
            // TODO Auto-generated method stub
            return name;
        }
    
        @Override
        public List<Oper> ops() {
            // TODO Auto-generated method stub
            return Arrays.asList(new Oper(){
                @Override
                public String comm() {
                    // TODO Auto-generated method stub
                    return name +" do1";
                }
            },new Oper(){
                @Override
                public String comm() {
                    // TODO Auto-generated method stub
                    return name+" do2";
                }
            });
        }
        
    }
  • 相关阅读:
    js经典试题之数据类型
    js单行写一个评级组件
    Spring Cloud Gateway的全局异常处理
    spring cloud gateway 全局过滤器
    公司ES升级带来的坑怎么填?
    Sentinel: 分布式系统的流量防卫兵
    微信小程序之页面打开数量限制
    微信小程序登录那些事
    API数据加密框架monkey-api-encrypt
    微信小程序之启动页的重要性
  • 原文地址:https://www.cnblogs.com/Tsing-Evan/p/8440498.html
Copyright © 2011-2022 走看看