天天看點

02-動态代理動态代理

動态代理

靜态代理

interface ClothFactory{
    void produceCloth();
}
//代理類
class ProxyClothFactory implements ClothFactory{
    private ClothFactory factory;  //用被代理對象進行執行個體化

    public ProxyClothFactory(ClothFactory factory){
        this.factory=factory;
    }
    @Override
    public void produceCloth() {
        System.out.println("代理工廠做準備工作");
        factory.produceCloth();
    }
}
//被代理類
class NikeClothFactory implements ClothFactory{
    @Override
    public void produceCloth() {
        System.out.println("Nike工廠生産一批運動裝");
    }
}
public class StaticProxyTest {
    public static void main(String[] args) {
        //建立被代理類對象
        NikeClothFactory nike = new NikeClothFactory();
        //建立代理類對象
        ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike);
        proxyClothFactory.produceCloth();
    }
}
           

動态代理

interface Human{
    String getBelief();
    void eat(String food);
}
//被代理類
class SuperMan implements Human{

    @Override
    public String getBelief() {
        return "I believe I can fly!";
    }
    @Override
    public void eat(String food) {
        System.out.println("我喜歡吃"+food);
    }
}
/*
    要實作動态代理需要解決的問題:
        1、如何根據加載到記憶體中的b被代理類 動态建立一個d代理類及對象
        2、當通過d代理類的對象調用方法時 如何動态的去調用被代理類中的同名方法
 */
class ProxyFactory{
    //調用此方法 傳回一個代理類對象
    public static Object getProxyInstance(Object obj){//obj 被代理類的對象
        MyInvocationHandler hander = new MyInvocationHandler();
        hander.bind(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),hander);
    }
}
class MyInvocationHandler implements InvocationHandler{
    private Object obj;
    public void bind(Object obj){
        this.obj=obj;
    }
    //當我們通過代理類的對象 調用方法a時 就會自動調用如下方法 invoke()
    //被代理類要執行d的方法a的功能就聲明在invoke()中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //即為代理類對象調用的方法 c此方法也就作為被代理類對象要調用的方法
        //obj 被代理類的對象
        Object returnValue=method.invoke(obj,args);
        return returnValue;
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();
        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
        proxyInstance.getBelief();
        proxyInstance.eat("麻辣燙");
    }
}
           

lambda表達式

格式:

->lambdac操作符

->左邊:lambda形參清單(其實就是接口中抽象方法的x形參清單)

->右邊:lambda體 其實就是重寫的抽象方法的方法體

使用
  • 格式一 無參 無傳回值

    Runnable r1 =()->{System.out.println("hello ");};

  • 格式二 有一個參數 無傳回值

    Consumer con = (String str)->{System.out.println(str);}

  • 格式三 資料類型可忽略 可由編譯器推斷出來

    Consumer con = (str)->{System.out.println(str);};

  • 格式四 隻需要一個參數時 參數的小括号可以省略

    Consumer con = str -> {System.out.println(str);};

  • 格式五 需要兩個或更多的參數 多條執行語句 可以有傳回值

    Comparator com =(x,y)->{

    System.out.println("hi”);

    return Integer.compare(x,y);

    }

  • 格式六 隻有一條語句時 return與大括号如果有 都可以省略

    Comparator com = (x,y)->Integer.compare(x,y);

總結

左邊:形參清單的參數類型可以省略 如果隻有一個參數其()可以省略

右邊:如果隻有體中隻有一條執行語句 可以省略{}和return關鍵字

本質
作為函數式接口的執行個體
函數式接口
一個接口中隻聲明了一個抽象方法
方法引用