看完kotlin的函数、函数类型,Lambda表达式,再来看JAVA 8的语言新特性或是反过来,总之是结合起来会发现很有意思。
下面还是主要记录java 8的语言新特性:
参考:https://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html
Lambda表达式与Functional接口
简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),一个lambda可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。Lambda可以引用类的成员变量与局部变量(如果这些变量不是final的话,它们会被隐含的转为final,这样效率更高)。Lambda可能会返回一个值。返回值的类型也是由编译器推测出来的。如果lambda的函数体只有一行的话,那么没有必要显式使用return语句。
例如:
( String e ) -> {System.out.println( e );}
函数式接口就是一个具有一个方法的普通接口。像这样的接口,可以被隐式转换为lambda表达式。java.lang.Runnable与java.util.concurrent.Callable是函数式接口最典型的两个例子。在实际使用过程中,函数式接口是容易出错的:如有某个人在接口定义中增加了另一个方法,这时,这个接口就不再是函数式的了,并且编译过程也会失败。为了克服函数式接口的这种脆弱性并且能够明确声明接口作为函数式接口的意图,Java 8增加了一种特殊的注解@FunctionalInterface(Java 8中所有类库的已有接口都添加了@FunctionalInterface注解)。
例如:
@FunctionalInterface
public interface Functional {
void method();
}
接口的默认方法与静态方法
Java 8用默认方法与静态方法这两个新概念来扩展接口的声明。默认方法使接口有点像Traits(Scala中特征(trait)类似于Java中的Interface,但它可以包含实现代码。
例如:
private interface Defaulable {
// 实现类可以覆盖该方法
default String notRequired() {
return "Default implementation";
}
}
Java 8带来的另一个的特性是接口可以声明(并且可以提供实现)静态方法。
例如:
interface DefaulableFactory {
// Interfaces允许静态方法
static Defaulable create( Supplier< Defaulable > supplier ) {
return supplier.get();
}
}
方法引用
方法引用的种类:
- 引用静态方法
- 引用特定对象的实例方法
- 引用特定类的任意对象的方法
- 引用构造器
例如:
public class Person {
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}
]
// 静态方法引用
Person::compareByAge
引用特定对象的实例方法,语法:containingObject::instanceMethodName
例如:
class ComparisonProvider {
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
}
// JRE编译器推测类型参数例表,在这个例子参数就是(Person, Person)
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
引用特定类的任意对象的方法,语法:ContainingType::methodName
例如:
// 下面方法引用示例String::compareToIgnoreCase等价的lambda表达式:(String a, String b) -> a.compareToIgnoreCase(b)。
// 参数a,b是随意命名的目的是为了说明下面的示例。
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
引用构造器,语法Class::new
例如:
public static Car create( final Supplier< Car > supplier ) {
return supplier.get();
}
// 用Lambda表达式调用该方法:
Car newCar = Car.create(() -> {return new Car();});
// 用构造器引用替换Lambda表达式
Car newCar = Car.create(Car::new);
重复注解,扩展了注解的上下文
JAVA 8之前使用注解的一个限制是相同的注解在同一位置只能声明一次,不能声明多次。Java 8打破了这条规则,引入了重复注解机制,这样相同的注解可以在同一地方声明多次。重复注解机制本身必须用@Repeatable注解。Java 8扩展了注解的上下文。现在几乎可以为任何东西添加注解:局部变量、泛型类、父类与接口的实现,就连方法的异常也能添加注解。
根据上下文推断泛型类型参数推测方面有了提高
例如:List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.asList());
// Java 7需要写成:
List<String> stringList = new ArrayList<>();
stringList.add("A");
stringList.addAll(Arrays.<String>asList());
目的是学习与交流,水平有限,有错误或是不严谨之处还请留言指出,不胜感激。