当前位置:   article > 正文

JAVA8 吊爆天的 十大新特性详解(快快收下)_java新特性爆红

java新特性爆红

JAVA8 吊爆天的 十大新特性详解(快快收下)

前言:

Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级。毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。在本文中我们将学习这些新特性,并用实际的例子说明在什么场景下适合使用。

1. 简介

这个教程包含Java开发者经常面对的几类问题:

  • 语言
  • 编译器
  • 工具
  • 运行时(JVM)

2. Java语言的新特性

Java 8是Java的一个重大版本,有人认为,虽然这些新特性领Java开发人员十分期待,但同时也需要花不少精力去学习。在这一小节中,我们将介绍Java 8的大部分新特性。

2.1Lambda表达式和函数式接口

Lambda表达式(也称为闭包)是Java 8中最大和最令人期待的语言改变。它允许我们将函数当成参数传递给某个方法,或者把代码本身当作数据处理:函数式开发者非常熟悉这些概念。很多JVM平台上的语言(Groovy、Scala等)从诞生之日就支持Lambda表达式,但是Java开发者没有选择,只能使用匿名内部类代替Lambda表达式。

Lambda的设计耗费了很多时间和很大的社区力量,最终找到一种折中的实现方案,可以实现简洁而紧凑的语言结构。最简单的Lambda表达式可由逗号分隔的参数列表、->符号和语句块组成,例如:

Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );

在上面这个代码中的参数e的类型是由编译器推理得出的,你也可以显式指定该参数的类型,例如:

Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ) );

如果Lambda表达式需要更复杂的语句块,则可以使用花括号将该语句块括起来,类似于Java中的函数体,例如:

  1. Arrays.asList( "a", "b", "d" ).forEach( e -> {
  2. System.out.print( e );
  3. System.out.print( e );
  4. } );

Lambda表达式可以引用类成员和局部变量(会将这些变量隐式得转换成final的),例如下列两个代码块的效果完全相同:

  1. String separator = ",";
  2. Arrays.asList( "a", "b", "d" ).forEach(
  3. ( String e ) -> System.out.print( e + separator ) );

  1. final String separator = ",";
  2. Arrays.asList( "a", "b", "d" ).forEach(
  3. ( String e ) -> System.out.print( e + separator ) );

Lambda表达式有返回值,返回值的类型也由编译器推理得出。如果Lambda表达式中的语句块只有一行,则可以不用使用return语句,下列两个代码片段效果相同:

Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );

  1. Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
  2. int result = e1.compareTo( e2 );
  3. return result;
  4. } );

Lambda的设计者们为了让现有的功能与Lambda表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念。函数接口指的是只有一个函数的接口,这样的接口可以隐式转换为Lambda表达式。java.lang.Runnable
java.util.concurrent.Callable是函数式接口的最佳例子。在实践中,函数式接口非常脆弱:只要某个开发者在该接口中添加一个函数,则该接口就不再是函数式接口进而导致编译失败。为了克服这种代码层面的脆弱性,并显式说明某个接口是函数式接口,Java 8 提供了一个特殊的注解@FunctionalInterface(Java 库中的所有相关接口都已经带有这个注解了),举个简单的函数式接口的定义:

  1. @FunctionalInterface
  2. public interface Functional {
  3. void method();
  4. }

不过有一点需要注意,默认方法和静态方法不会破坏函数式接口的定义,因此如下的代码是合法的。

  1. @FunctionalInterface
  2. public interface FunctionalDefaultMethods {
  3. void method();
  4. default void defaultMethod() {
  5. }
  6. }

Lambda表达式作为Java 8的最大卖点,它有潜力吸引更多的开发者加入到JVM平台,并在纯Java编程中使用函数式编程的概念。如果你需要了解更多Lambda表达式的细节,可以参考官方文档。

2.2 接口的默认方法和静态方法

Java 8使用两个新概念扩展了接口的含义:默认方法和静态方法。默认方法使得接口有点类似traits,不过要实现的目标不一样。默认方法使得开发者可以在 不破坏二进制兼容性的前提下,往现存接口中添加新的方法,即不强制那些实现了该接口的类也同时实现这个新加的方法。

默认方法和抽象方法之间的区别在于抽象方法需要实现,而默认方法不需要。接口提供的默认方法会被接口的实现类继承或者覆写,例子代码如下:

  1. private interface Defaulable {
  2. // Interfaces now allow default methods, the implementer may or
  3. // may not implement (override) them.
  4. default String notRequired() {
  5. return "Default implementation";
  6. }
  7. }
  8. private static class DefaultableImpl implements Defaulable {
  9. }
  10. private static class OverridableImpl implements Defaulable {
  11. @Override
  12. public String notRequired() {
  13. return "Overridden implementation";
  14. }
  15. }

Defaulable接口使用关键字default定义了一个默认方法notRequired()DefaultableImpl类实现了这个接口,同时默认继承了这个接口中的默认方法;OverridableImpl类也实现了这个接口,但覆写了该接口的默认方法,并提供了一个不同的实现。

Java 8带来的另一个有趣的特性是在接口中可以定义静态方法,例子代码如下:

  1. private interface DefaulableFactory {
  2. // Interfaces now allow static methods
  3. static Defaulable create( Supplier< Defaulable > supplier ) {
  4. return supplier.get();
  5. }
  6. }

下面的代码片段整合了默认方法和静态方法的使用场景:

  1. public static void main( String[] args ) {
  2. Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new );
  3. System.out.println( defaulable.notRequired() );
  4. defaulable = DefaulableFactory.create( OverridableImpl::new );
  5. System.out.println( defaulable.notRequired() );
  6. }

这段代码的输出结果如下:

  1. Default implementation
  2. Overridden implementation

由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()parallelStream()forEach()removeIf()等等。

尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考官方文档。

2.3 方法引用

方法引用使得开发者可以直接引用现存的方法、Java类的构造方法或者实例对象。方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/53054
推荐阅读
相关标签
  

闽ICP备14008679号