[译]Java 8 – Functional Interfaces

原文:http://www.javabeat.net/java-8-functional-interfaces/

什么是函数式接口?

函数式接口是有一个抽象方法的接口。根据Java8的规范,如果接口中的一个方法遵从以下规则那么可以认为它就是函数式接口:

• 如果一个接口只有一个抽象方法,这个接口可以被认作是函数式接口。

• 一个函数式接口可以有任何多个默认方法和一个抽象方法。默认方法用“default”关键字定义在接口内,这是Java8里面的新特性。

• 如果一个接口继承自其它函数式接口并且其内部没有定义任何其它方法,那么它也可以被认作是函数式接口,因为它从父接口中继承了一个抽象方法。

@FunctionalInterface注解被编译器用来检测一个接口是否是合法的函数式接口。一个函数式接口不强制规定必须使用@FunctionalInterface注解表明。

• 除了一个自己定义的抽象方法以外,还可以声明Object类中的任何方法作为抽象方法,此接口仍然是一个函数式接口。

• 以前被称为一个抽象方法接口 (SAMI)的接口。

• 一些函数式接口的例子:java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, java.util.concurrent.Callable。

函数式接口的例子

What are Functional Interfaces and Functional Descriptor?

Lambda Expressions in Java 8

让我们看一下Java API中的几个函数式接口的例子:

RunnableComparator接口就是函数式接口,

Runnable.java

1
2
3
interface Runnable {
void run();
}

Comparator.java

1
2
3
4
interface Comparator<T>; {
boolean equals(Object obj);
int compare(T o1, T o2);
}

让我们看看下面几个用户自定义的函数式语义接口

Deployable.java

1
2
3
4
5
package net.javabeat;
public interface Deployable {
boolean someWork(Iterable<String> arg);
}

Integrateable.java

1
2
3
4
5
package net.javabeat;
public interface Integrateable {
boolean someWork(Iterable<String> arg);
}

Useable.java

1
2
3
4
5
package net.javabeat;
@FunctionalInterface
public interface Useable extends Deployable, Integrateable{
}

Useable是一个函数式接口因为它继承Deployable和Integrateable的两个方法。如果你观察这两个接口,会发现它们有相同的签名(译者注:方法签名即由方法名称和一个参数列表[方法的参数的顺序和类型]组成),所以继承过来的方法逻辑上代表了一个单一的方法。

@FunctionalInterface注解可以被用在接口声明的顶部。

Deployable.java

1
2
3
4
5
package net.javabeat;
public interface Deployable {
Iterable someWork(Iterable<String> arg);
}

创建函数式接口的实例

创建函数式接口的实例有以下三种方式:

  1. 创建一个类似并实现你的函数式接口,然后只需要在这个类的实例中使用接口(Java8之前使用)。
  2. 创建方法引用表达式(匿名实例,Java8之前使用)。
  3. 使用Lambda表达式(Java8新特性可使用)

观察下面的示例,使用第1、2中方式创建函数式接口的实例。第3中方式将会在Lambda Expression部分解释。

SomeInterface.java

1
2
3
4
5
package net.javabeat;
public interface Deployable {
Integer someWork();
}

UIComponent.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package net.javabeat;
public class UIComponent {
public static void main(String [] args){
Deployable deployable = new Deployable() {
@Override
public Integer someWork() {
return 1;
}
};
System.out.println("Invoke SomeWork Method Against SomeInterface :: "+deployable.someWork());
}
}

输出:
Invoke SomeWork Method Against SomeInterface :: 1

相关文章:

放个另一篇文章的翻译:Kotin中的Interface