动态代理
静态代理
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关键字
作为函数式接口的实例函数式接口一个接口中只声明了一个抽象方法方法引用