个人对于Java8的一些新特性总结

目前Java8已经发布很多个版本了,对于Java8中的新特性虽然有各位大神进行jdk8的英文特性文档翻译,但都太官方化语言,对照几篇翻译本人对新特性文档做一下总结,以帮助我和各位不了解Java8新特性的Java工程师们对其进行了解,水平有限,有错误之处请各位不吝赐教。

  接口的改善(接口的默认方法):

  在Java8以前接口的作用主要是对实现接口的类进行规范的,在其中只能定义常量和抽象方法。

  Java8中允许我们去定义一个非抽象方法,这个方法是一个静态方法 ,用default关键字来定义这个默认方法,同时这个特性也被称为扩展方法,代码如下。

 1   interface Formula {
 2
 3       double calculate(int a);
 4
 5       Public default double sqrt(int a) {
 6
 7           return Math.sqrt(a);
 8
 9       }
10
11   }    

  实现Formula接口的类只需实现calculate方法,而sqrt方法已经在接口中实现,从而子类无需实现可直接调用,以下是一个匿名实现的代码。

  

 1     Formula formula = new Formula() {
 2
 3   @Override
 4   public double calculate(int a) {
 5
 6       return sqrt(a * 100);
 7
 8       }
 9
10   };
11
12   formula.calculate(100);     // 100.0
13
14   formula.sqrt(16);           // 4.0

  且在Java8的核心类库的接口中大量的默认方法也被添加,这在API手册中应该可以查到。

  函数接口:

  函数接口是Java8中引入的一个核心概念,既若一个接口只定义了唯一一个抽象方法,那么这个接口就成为一个函数接口,如线程接口java.lang.Runnable就是一个典型的函数接口,在Runnable接口中只有public abstract void run();方法这一个抽象方法。

  abstract关键词为隐含的,只是为了表示此为一个函数式接口,并不一定需要。而且函数接口中可以定义任意多的默认方法,这完全由工程师自己决定。

  新添加一个Annotation(注解)@FunctionalInterface,这个注解可以放在接口前,用来表示此接口是一个函数接口,此注解和@Override作用差不多,只声明使用意图,避免错误使用,并不会被编译。

  Lambdas表达式:

  Lambdas表达式为Java8提供更简洁和更具可读性的代码。

  在Java8之前匿名内部类的创建代码常常会使得代码阅读性降低,如下是实现一个字符串的匿名内部类:

 1   List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
 2
 3   Collections.sort(names, new Comparator<String>() {
 4
 5   @Override
 6   public int compare(String a, String b) {
 7
 8           return b.compareTo(a);
 9
10       }
11
12   });

  这种代码对程序工程师们非常不友好的,尤其对于那些经验不丰富的人来说若在程序内有大量这种代码简直是一场灾难。

  用Lambdas表达式可以简化这种匿名类的创建:

  Collections.sort(names, (String a, String b) -> {

      return b.compareTo(a);

  });

  显然这种使用Lambdas表达式的方式可以使代码阅读性更加的好,当然我们可以把以上代码写的更短,对于函数体只有一行的,可以去掉{}和return关键词:

  

Collections.sort(names, (String a, String b) -> b.compareTo(a));

  但是也可以更加的短:

  

Collections.sort(names, (a, b) -> b.compareTo(a));

  因为Java编译器可以自动推导出参数类型,所以可以不用再一次写类型。这里还有一些Lambdas表示式的列子,以帮助大家更好的理解Lambdas表达式。

  左边是指定类型的参数列表,右边是return代码块:

 

 (int a, int b)->{return x+y;}

  左边是推导类型的参数列表,右边为返回值:

 

(x, y)->x+y

  左边为单参数的推导列表,右边是返回值:

  

x->x*x

  左边无参数(官方名称: "burger arrow"),右边一个返回值:

  

()->x

  左边推导类型单一参数,右边无返回值代码块(void):

  

x -> { System.out.println(x); }

  静态方法引用:

  

String::valueOf等价于x -> String.valueOf(x)

  非静态方法引用:

  

Object::toString等价于x -> x.toString()

  继承的函数引用:

  

x::toString等价于() -> x.toString()

  构造函数引用:

  

ArrayList::new等价于() -> new ArrayList<>()

  重载对Lambdas同样有效。一个lambda和给定的函数式接口在“外型”匹配的时候兼容。通过“外型”,我指向输入、输出的类型和声明检查异常。

  两个例子:

  

Comparator<String> c = (a, b) -> Integer.compare(a.length(),b.length());

  一个Comparator<String>的compare方法需要输入两个参数,然后返回一个int。这和lambda右侧的一致,因此这个任务是有效的。

  

Runnable r = () -> { System.out.println("Running!"); }

  一个Runnable的run方法不需要参数也无返回值。这和lambda表达式右侧一致,所以任务有效。

  在抽象方法的签名里的检查异常(如果存在)也很重要。如果函数式接口在它的签名里声明了异常,lambda只能抛出受检查异常。

  捕获和非捕获的Lambda表达式:

  当Lambda表达式访问一个定义在Lambda表达式体外的非静态变量或者对象时,这个Lambda表达式称为“捕获的”。比如,下面这个Lambda表达式捕捉了变量x:

  int x = 5;

  return y -> x + y;

  为了保证这个lambda表达式声明是正确的,被它捕获的变量必须是“有效final”的。所以要么它们需要用final修饰符号标记,要么保证它们在赋值后不能被改变。

  从性能上一个非捕获的Lambda比捕获的Lambda通常更高效。

  Lambda不提供的一些特性

  Non-final* 变量捕获 - 如果一个变量被赋予新的数值,它将不能被用于lambda之中。"final"关键字不是必需的,但变量必须是“有效final”的。

  

    int count = 0;

  List<String> strings = Arrays.asList("a", "b", "c");

  strings.forEach(s -> {
      count++; // 错误: 不能修改 count 的值
 });

  异常的透明度 - 如果一个检测的异常可能从lambda内部抛出,功能性的接口也必须声明检测异常可以被抛出。这种异常不会散布到其包含的方法。

  控制流程 (break, early return) - 传统的继续方式有可能通过在lambda之内放置 "return;"来实现。但是,没有办法中断循环或者从lambda中通过包含方法的结果返回一个数值。

 

 final String secret = "foo"; boolean containsSecret(Iterable<String> values) {

  values.forEach(s -> { if (secret.equals(s)) {

  ??? // 想终止循环并返回 true, 但是不行 }

      });

  }

  抽象类不能被Lamdba实例化 - 这样做引发的最常见的争论就是会增加阅读lambda的难度。以这种方式实例化一段抽象类将导致隐藏代码的执行:抽象类的构造方法。

  以上是本人对其他一些翻译后的Java8文档的梳理总结,在总结过程中也发现翻译后的文档有诸多语义不明确的地方,对照原文进行理解,但限于本人英文能力有限,只对部分细枝末节的地方进行了修改,若大家有更好的理解还希望能多与大家交流进步。关于Java8中的新增和优化的API部分将另为进行梳理总结。

时间: 2024-12-28 14:52:09

个人对于Java8的一些新特性总结的相关文章

JAVA8 十大新特性详解

本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口,Map以及全新的日期API “Java is still not dead—and people are starting to figure that out.” 本教程将用带注释的简单代码来描述新特性,你将看不到大片吓人的文字. 一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方

java8十大新特性浅谈

本文将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口,Map以及全新的日期API "Java is still not dead-and people are starting to figure that out." 本文将用带注释的简单代码来描述新特性,你将看不到大片吓人的文字. 一.接口的默认方法 Java 8允许我们给接口添加一个非抽

Java8 的一些新特性的学习理解

近期在学习队列相关的一些知识,在学习过程中发现Iterable<T>接口中新增了两个新的方法,出于好奇,就想知道这是什么东东,干什么用的.俗话说:实践出真知,所以就有了以下反复的测试. 先看下新增的这两个方法: 1 default void forEach(Consumer<? super T> action) { 2 Objects.requireNonNull(action); 3 for (T t : this) { 4 action.accept(t); 5 } 6 } 1

java8 十大新特性

这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布. 在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API仍然有可能改变,我会尽我最大的努力保持这份文档跟得到Java 8的改动. Java 8的预览版,也就是 “Project Lambda”,现在可以从java.net下载到. 我使用了IntelliJ的预览版做我的IDE,在我看来他是目前支持java 8特性最好的一个IDE,你可以从这里下载到. 由于

Java8的重要新特性

一.Lambda表达式 java8中Lambda表达式的书写方式: (参数) -> 表达式 (参数) -> 单行语句 (参数) -> { 语句 } 1.Lambda遍历List和Map package com.yanwu.www.demo; /** * @author Harvey */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; pu

Java8中的新特性Optional

Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象.Optional 是个容器:它可以保存类型T的值,或者仅仅保存null.Optional提供很多有用的方法,这样我们就不用显式进行空值检测.Optional 类的引入很好的解决空指针异常. package com.demo.optional; import lombok.extern.slf4j.Slf4j; import org.junit.Test; im

Java8部分新特性的学习

Java8中的新特性 一.Lambda表达式 Lambda表达式可以理解为一种可传递的匿名函数:它没有名称,但又参数列表.函数主体.返回类型,可能还有一个可以抛出的异常列表. 匿名:和匿名类类似的,它没有明确的名字 函数:Lambda函数不属于某个特定的类,但和方法一样都具有参数列表.函数主体.返回类型,还可以有抛出的异常列表 传递:Lambda表达式可以作为参数传递给方法或者存储在变量中. Lambda表达式的基本形式: (parameters)-> expression 或(paramete

java8新特性——简介

java8问世已经有好长时间了,但是之前项目中都没有使用到,所以一直都只是了解一些,近期刚刚换了加新公司,在开发中需要使用到java8来开发,所以也是马上赶来学习一下java8得新特性. 一.新特性 1.Lambda表达式(重要) 2.函数式接口 3.方法引用与构造器引用 4.stream API(重要) 5.接口中得默认方法和静态方法 6.新时间日期 以上几个知识点就是打算后期主要学习得几个特性. 二.优点 1.速度快,效率搞.(底层数据结构做了优化,gc做了优化) 2.开发方便,更简洁.(l

java8新特性——Lambda表达式

上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开始学学习. 一.为什么要使用Lambda表达式 Lambda是一个匿名函数,我们可以baLambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁,更灵活的代码.作为一种更紧凑得代码风格,使得java得语言表达能力得到提升.Lambda表达式需要函数式接口的支持,接口中