1、java引入lambada 表达式的背景
Java 是一流的面向对象语言,除了部分简单数据类型,Java 中的一切都是对象,即使数组也是一种对象,每个类创建的实例也是对象。
在 Java 中定义的函数或方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例。
在Java的面向对象的世界里面,“抽象”是对数据的抽象,而“函数式编程”是对行为进行抽象,在现实世界中,数据和行为并存,程序也是如此。
所以java8中lambada表达式的出现也就弥补java在对行为进行抽象方面的缺失。
2、 函数式接口
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口(除了隐含的Object对象的公共方法),
因此最开始也就做SAM类型的接口(Single Abstract Method)。
首次看到这个概念的时候,有些迷茫。因为接口中的方法都是public abstract 的(即便省略掉这两个关键字也是ok的,接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)),那么上面的定义就变成了:只有一个方法声明的接口就是函数式接口。
但是实际上在代码中看到的函数式接口有包含一个方法的,也有包含多个方法的,这就让我迷茫了。
例如下面的两个函数式接口:Runnable 和 Consummer:
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
java.util.function.Consummer:
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
从上面我们了解了原因在于:函数式接口中除了那个抽象方法外还可以包含静态方法和默认方法。
Java 8以前的规范中接口中不允许定义静态方法。 静态方法只能在类中定义。 Java 8中可以定义静态方法。
一个或者多个静态方法不会影响SAM接口成为函数式接口。
Java 8中允许接口实现方法, 而不是简单的声明, 这些方法叫做默认方法,使用特殊的关键字default。
因为默认方法不是抽象方法,所以不影响我们判断一个接口是否是函数式接口。
可参考java8-lambada表达式和函数式编程浅析
链接文字