java8新特性(一)
2018-02-09 00:00
302 查看
一、Lambda表达式和函数式接口
1、Lambda表达式(也就是闭包):它允许我们将一个函数当作方法的参数(传递函数),这是每个函数式编程者熟悉的概念。其实1.7以下就有支持Lambda表达式的,但是java程序员没有选择,只能使用匿名内部类来代替Lambda表达式。
简单的Lambda表达式:参数列表 -> 功能语句块
示例一:
示例二:
注意:编译器会根据上下文来推测参数的类型,或者你也可以显示地指定参数类型,只需要将类型包在括号里
示例三:Lambda表达式可能会有返回值,编译器会根据上下文推断返回值的类型。如果lambda的语句块只有一行,不需要return关键字。下面两段代码是等效的:
2、函数式接口:语言的设计者们为了让现有的功能和Lambda表达式友好兼容,于是就有了函数式接口,函数式接口是一种只有一个方法的接口,函数式接口可以隐式的转换成Lambda表达式。
java.lang.Runnable和java.util.concurrent.Callable是函数式接口最好的两个例子。但是在实践中,函数接口是非常脆弱的,只要有人在接口里添加多一个方法,那么这个接口就不是函数接口了,就会导致编译失败。Java 8提供了一个特殊的注解@FunctionalInterface来克服上面提到的脆弱性并且显示地表明函数接口的目的(java里所有现存的接口都已经加上了@FunctionalInterface)。
简单的函数接口定义:
记住默认的方法和静态方法不会违反函数接口的约定,下面讲讲。
2.1、接口的默认方法和静态方法
默认方法:默认方法允许我们在接口里添加新的方法,而不会破坏实现这个接口的已有类的兼容性,也就是说不会强迫实现接口的类实现默认方法。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供一个默认的方法实现,所有这个接口的实现类都会通过继承得倒这个方法(如果有需要也可以重写这个方法)
示例:
Java 8 的另外一个有意思的新特性是接口里可以声明静态方法,并且可以实现
接口的静态方法和默认方法放在一起的示例(::new 是构造方法引用,后面会有详细描述)
控制台输出:
Default implementation
Overridden implementation
二、方法引用
方法引用提供了一个很有用的语义来直接访问类或者实例的已经存在的方法或者构造方法。java8中提供了4种方法引用,用Car类作示例
1、构造方法引用
语法:Class :: new
泛型语法:Class<T> :: new
注意:构造方法没有参数
示例:
2、静态方法引用
语法:Class::static_method
注意:这个静态方法只支持一个类型为Car的参数
示例:
3、类实例的方法引用
语法:Class::method
注意:方法没有参数
示例:
4、引用特殊类的方法
语法:instance::method
注意:只接受Car类型的一个参数
示例:
运行这些例子我们将会在控制台得到如下信息(Car的实例可能会不一样):
Collided com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Repaired com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Following the com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
参考地址:http://ifeve.com/java-8-features-tutorial/
1、Lambda表达式(也就是闭包):它允许我们将一个函数当作方法的参数(传递函数),这是每个函数式编程者熟悉的概念。其实1.7以下就有支持Lambda表达式的,但是java程序员没有选择,只能使用匿名内部类来代替Lambda表达式。
简单的Lambda表达式:参数列表 -> 功能语句块
示例一:
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
示例二:
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ) );
注意:编译器会根据上下文来推测参数的类型,或者你也可以显示地指定参数类型,只需要将类型包在括号里
示例三:Lambda表达式可能会有返回值,编译器会根据上下文推断返回值的类型。如果lambda的语句块只有一行,不需要return关键字。下面两段代码是等效的:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> { int result = e1.compareTo( e2 ); return result; } );
2、函数式接口:语言的设计者们为了让现有的功能和Lambda表达式友好兼容,于是就有了函数式接口,函数式接口是一种只有一个方法的接口,函数式接口可以隐式的转换成Lambda表达式。
java.lang.Runnable和java.util.concurrent.Callable是函数式接口最好的两个例子。但是在实践中,函数接口是非常脆弱的,只要有人在接口里添加多一个方法,那么这个接口就不是函数接口了,就会导致编译失败。Java 8提供了一个特殊的注解@FunctionalInterface来克服上面提到的脆弱性并且显示地表明函数接口的目的(java里所有现存的接口都已经加上了@FunctionalInterface)。
简单的函数接口定义:
@FunctionalInterface public interface Functional { void method(); }
记住默认的方法和静态方法不会违反函数接口的约定,下面讲讲。
@FunctionalInterface public interface FunctionalDefaultMethods { void method(); default void defaultMethod() { } }
2.1、接口的默认方法和静态方法
默认方法:默认方法允许我们在接口里添加新的方法,而不会破坏实现这个接口的已有类的兼容性,也就是说不会强迫实现接口的类实现默认方法。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供一个默认的方法实现,所有这个接口的实现类都会通过继承得倒这个方法(如果有需要也可以重写这个方法)
示例:
private interface Defaulable { // Interfaces now allow default methods, the implementer may or // may not implement (override) them. default String notRequired() { return "Default implementation"; } } private static 3ff0 class DefaultableImpl implements Defaulable { } private static class OverridableImpl implements Defaulable { @Override public String notRequired() { return "Overridden implementation"; } }
Java 8 的另外一个有意思的新特性是接口里可以声明静态方法,并且可以实现
private interface DefaulableFactory { // Interfaces now allow static methods static Defaulable create( Supplier< Defaulable > supplier ) { return supplier.get(); } }
接口的静态方法和默认方法放在一起的示例(::new 是构造方法引用,后面会有详细描述)
public static void main( String[] args ) { Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new ); System.out.println( defaulable.notRequired() ); defaulable = DefaulableFactory.create( OverridableImpl::new ); System.out.println( defaulable.notRequired() ); }
控制台输出:
Default implementation
Overridden implementation
二、方法引用
方法引用提供了一个很有用的语义来直接访问类或者实例的已经存在的方法或者构造方法。java8中提供了4种方法引用,用Car类作示例
public static class Car { public static Car create( final Supplier< Car > supplier ) { return supplier.get(); } public static void collide( final Car car ) { System.out.println( "Collided " + car.toString() ); } public void follow( final Car another ) { System.out.println( "Following the " + another.toString() ); } public void repair() { System.out.println( "Repaired " + this.toString() ); } }
1、构造方法引用
语法:Class :: new
泛型语法:Class<T> :: new
注意:构造方法没有参数
示例:
final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );
2、静态方法引用
语法:Class::static_method
注意:这个静态方法只支持一个类型为Car的参数
示例:
cars.forEach( Car::collide );
3、类实例的方法引用
语法:Class::method
注意:方法没有参数
示例:
cars.forEach( Car::repair );
4、引用特殊类的方法
语法:instance::method
注意:只接受Car类型的一个参数
示例:
final Car police = Car.create( Car::new ); cars.forEach( police::follow );
运行这些例子我们将会在控制台得到如下信息(Car的实例可能会不一样):
Collided com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Repaired com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Following the com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
参考地址:http://ifeve.com/java-8-features-tutorial/
相关文章推荐
- Java 1.5,1.6,1.7新增的特性
- Java特性多态
- 深入理解Java虚拟机JVM高级特性与最佳实践阅读总结—— 第七章 虚拟机类加载机制
- java_jdk1.5部分新特性
- Java中事务的特性
- java8,你应该了解的新特性(空指针终结者:Optional 类)
- [置顶] Java 多线程学习笔记(七)数据类型String的常量池特性
- java8的新特性以及用法简介
- JAVA注解和C#特性
- java新特性——对数组的支持(可变参数、foreach)
- java8新特性--集合、Optional 类
- Java 9的9个新特性
- java8新特性源码解析
- java技术加强之其他1.5特性
- 【java高级特性之反射】数组的反射
- Java多态特性
- JAVA 8 特性
- javaSE_07Java中类和对象-封装特性--练习
- Android Studio对于Java8特性的支持
- 体验Java 5.0的新增语言特性