動态代理
靜态代理
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關鍵字
作為函數式接口的執行個體函數式接口一個接口中隻聲明了一個抽象方法方法引用