Functional Interfaces
How does lambda expressions fit into Javas type system? Each lambda corresponds to a given type, specified by an interface. A so called functional interface must contain exactly one abstract method declaration. Each lambda expression of that type will be matched to this abstract method. Since default methods are not abstract you're free to add default methods to your functional interface.
We can use arbitrary interfaces as lambda expressions as long as the interface only contains one abstract method. To ensure that your interface meet the requirements, you should add the @FunctionalInterface
annotation. The compiler is aware of this annotation and throws a compiler error as soon as you try to add a second abstract method declaration to the interface
功能性接口
lambda表达式如何融入到java类型体系?每个lamba对应一个由一个接口定义的特定类型。这种功能性接口有且只能有一个抽象方法声明。每个lambda表达式匹配这个抽象方法。因为默认方法不是抽象方法,可以功能性接口添加默认方法。
我们可以使用任意接口当做lambda表达式只要这个接口只包含一个抽象方法。为保证接口满足限定条件,要增加FunctionalInterface
注解。编译器可以感知注解,当增加第二个抽象方法的时候会抛出异常。
public class MethodRef {
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
public static void main(String[] args) {
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted); // 123
Converter<String, Integer> converter2 = Integer::valueOf;
Integer converted2 = converter.convert("123");
System.out.println(converted2); // 123
}
}
java8允许通过:: 符号引用方法和构造器。上面展示了应用静态方法。下面是对象方法引用。
public class ObjectMethodRef {
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
static class Something {
String startsWith(String s) {
return String.valueOf(s.charAt(0));
}
}
public static void main(String[] args) {
Something something = new Something();
Converter<String, String> converter = something::startsWith;
String converted = converter.convert("Java");
System.out.println(converted); // "J"
}
}
下面是构造器引用
public class ConstructorMethodRef {
static class Person {
String firstName;
String lastName;
Person() {
}
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + "]";
}
}
interface PersonFactory<P extends Person> {
P create(String firstName, String lastName);
}
public static void main(String[] args) {
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
System.out.println(person);
}
}