jkd1.8 lambda 表达式之函数式接口

函数式接口(也叫SAM接口,Single Abstract Method)的对象可以作为函数的参数,这样参数在引用时,可以以lambda表达式的方式出现。 
每个函数式接口里仅允许有一个抽象方法,这个方法叫做函数式方法,lambda表达式的参数和返回类型必须和该函数的参数和返回类型保持一致。你无须去创建这个类,编译器会帮你实现。

函数式接口仅允许有一个抽象方法,用注解@FunctionalInterface 标识,如果不写默认也是函数式接口

  • 仅允许有一个抽象方法
@FunctionalInterface
public interface CallBack {
    T callback();
}

 

因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的 

  • 接口里有一个默认方法
@FunctionalInterface
public interface CallBack {
    T callback();
    default void method1(){
        System.out.println();
    }
    default void method2(){
        System.out.println();
    }
    default void method3(){
        System.out.println();
    }
}
  • 函数式接口里允许定义静态方法

函数式接口里是可以包含静态方法,因为静态方法不能是抽象方法,是一个已经实现了的方法,所以是符合函数式接口的定义的,静态方法默认是public的 

@FunctionalInterface
public interface CallBack {
    T callback();
    static void method(){
        
    }
    static void method2(){

    }
}
  • 函数式接口的使用 

 我自定义了ReentranReadLock类,其中定义了readLock方法来对所做的事情进行前置加锁,后置解锁的效果

public class ReentranReadLock {
    private  final ReentrantReadWriteLock locker;

    public ReentranReadLock() {
        locker = new ReentrantReadWriteLock();
    }

    public  T readlock(CallBack callBack){
        this.locker.readLock().lock();
        Object object;
        try {
            //lambda表达式的调用
            object = callBack.callback();
        }finally {
            this.locker.readLock().unlock();
        }
        return (T) object;
    }
}

测试代码

public class MyTest {
    private static String str = "hello world";
    public static void main(String[] args) {
        ReentranReadLock readLock = new ReentranReadLock();
        //lambda表达式相当于是callback方法的重写
        String result = readLock.readlock(() -> str);
        System.out.println(result);
    }
}

多线程Runable接口就是函数式接口,只有一个抽象方法run,所以可以使用lambda表达式来简化,我看有博客介绍说能替代内部类,这个说法不太准确,Runable接口使用如下

        //不使用lambda表达式
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("hello");
                    }
                }
        ).start();


        //使用lambda表达式
        new Thread(() -> System.out.println("hello")).start();

总结,其实我调用的时候,相当于我把接口CallBack接口当参数传进来,函数式接口中只有一个抽象方法,所以lambda表达式相当于对这个抽象方法进行了重写。我的这个例子实现了对目标进行前置后置操作,我的理解有点像AOP编程,是不是很牛逼。

你可能感兴趣的:(java,lambda,函数式接口)