JAVA中静态代理和Lamda表达式

文章目录

    • 静态代理
      • 静态代理优缺点
        • 优点:
        • 缺点:
    • Lamda表达式

平常我们最常见的动态代理,那么对应的也有静态代理,在此我们来了解一下什么是静态代理以及静态代理的优缺点。

静态代理

静态代理优缺点

优点:

代理使得调用方不需要知道实现类是什么,怎么做的,而只需知道如何代理即可。

缺点:

1)代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

2)代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。如果代码只是为***类提供了代理,在此时还需要对其他类例如:***1类提供代理的话,就需要我们再次添加代理***1的代理类。
我们根据代码来具体看一下静态代理
实现功能:婚庆公司代理你结婚的筹备事宜…

//静态代理
public class StaticProxy {
    public static void main(String[] args) {
        //代理对象  代理 真实对象
        Ming ming = new Ming();
        new WeddingCompany(ming).happyMarry();
    }
}

//真实对象:小明
class Ming implements Marry{

    @Override
    public void happyMarry() {
        System.out.println("我要结婚了,好hi呦");
    }
}


//代理对象:婚庆公司
class WeddingCompany implements Marry{

    //婚庆需要有你这个人 , 代理对象需要代理一个真实对象
    private Marry ming;

    public WeddingCompany(Marry ming){
        this.ming = ming;
    }

    @Override
    public void happyMarry() {
        before();
        this.ming.happyMarry();//你要结婚
        after();
    }

    private void before() {
        System.out.println("结婚之前,布置洞房");
    }
    private void after() {
        System.out.println("结婚之后,催你收钱");
    }

}

//共同的接口:结婚
interface Marry{
    void happyMarry();
}

解释:目标为小明,小明要结婚,那么小明和婚庆公司直接的联系为结婚.因此先创建一个结婚接口,其次小明和婚庆公司都实现这个接口,并重写了happyMarry()方法,婚庆公司也需要一个对象来实施结婚的事宜,因此在婚庆公司类中创建了一个对象ming,实行了静态代理…
因此可以发现,静态代理其实婚庆公司代理了小明结婚的筹备事宜,他们共同实现了Marry这个接口,看到这里有没有觉得静态代理很眼熟呢?没错,就是我们上篇博客讲到的Runnable接口的实现,Runnable接口也是需要自己定义一个实现类,并重写run()方法,之后通过new Thread(实现类对象).start() 来启动线程。原因也是因为Thread和自己定义的实现类都实现了Runnable接口(可以自己查看Thread类的源码,其中有实现Runnable接口),因此Runnable方式其实就是静态代理。
上篇博客链接:JAVA中线程的三种创建方法

上面也提到了静态代理的缺点,就是使用起来会显得代码比较繁琐,但是JDK8中新增了一个Lamda表达式,可以使我们的代码更为的简单。

Lamda表达式

为什么要使用lambda表达式

  1. 避免匿名内部类定义过多
  2. 可以让你的代码看起来很简洁
  3. 去掉了一堆没有意义的代码,只留下核心的逻辑。

Lamda表达式的写法为:
()->{}
其实质属于函数式编程的概念
既然提到了函数式接口编程,我们先来了解一下什么是函数式接口编程:
任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。

public interface Runnable {
	public abstract void run();
}

Runnable接口就是一个函数式接口,下面我们从静态内部类到局部内部类,到匿名内部类,再到Lamda表达式说起:

public class Test01 {

    //静态内部类
    static class Test02 implements Runnable{
        @Override
        public void run() {
            System.out.println("你好呀lambda!");
        }
    }


    public static void main(String[] args) {
        Test02 test02 = new Test02();
        new Thread(test02).start();

        //局部内部类
        class Test03 implements Runnable{
            @Override
            public void run() {
                System.out.println("你好呀lambda2!");
            }
        }

        Test03 test03 = new Test03();
        new Thread(test03).start();


        //匿名内部类, 需要有一个借口或者父类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("你好呀lambda3!");
            }
        }).start();

        //lambda  jdk.8新增方式
        new Thread(()->{
            System.out.println("你好呀lambda4!");
        }).start();
    }
}

上面写的是Lamda没有传递参数的情况,下面我们写Lambda表达式传递参数的情况,并且仔细讲解:Lamda表达式的各种写法


public class Test03 {
    public static void main(String[] args) {
        ILove love = new Love();
        love.lambda(1);//第一种最为普通的静态代理

        //匿名内部类
        love = new ILove() {
            @Override
            public void lambda(int a) {
                System.out.println("我开始喜欢lambda了...."+a);
            }
        };
        love.lambda(2);


        //lambda表达式
        love = (int a)->{
            System.out.println("我开始喜欢lambda了...."+a);
        };
        love.lambda(3);


        //简化1: 去掉括号()有一个参数的形式下可以这么做...
        love = a->{
            System.out.println("我开始喜欢lambda了...."+a);
        };
        love.lambda(4);


        //简化2:之前基础就懂的,在{}内只有一行代码的情况下,是可以省略掉{}的,所以在此处去掉花括号{}
        love = a->System.out.println("我开始喜欢lambda了...."+a);
        love.lambda(5);

    }
}
//函数式接口
interface ILove{
    void lambda(int a);
}

class Love implements ILove{
    @Override
    public void lambda(int a) {
        System.out.println("我开始喜欢lambda了...."+a);
    }
}

最后再强调一遍:Lamda表达式必须是函数式接口(任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。)!!!

你可能感兴趣的:(2019重学Java,静态代理,Lamda表达式)