JDK8

我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述JDK8相关的知识,希望能为你提供帮助。
介绍随着java的发展,越来越多的企业开始使用??java8??版本。Java8是自从java5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。
????JDK8新增的特性如下

  • Lambda表达式
  • 新的日期API、Datetime
  • 引入Optional防止空指针异常
  • 使用Base64
  • 接口的默认方法和静态方法
  • 新增方法引用格式
  • 新增Stream类
  • 注解相关的改变
  • 支持并行(parallel)数组
  • 对并发类(Concurrency)的扩展
  • JavaFX
接口新特性接口默认方法当我们去实现某个框架提供的一个接口时,需要实现其所有的抽象方法,当该框架更新版本,在这个借口中加入了新的抽象方法时,我们就需要对项目重新编译,并且实现其新增的方法。当实现类太多时,操作起来很麻烦
JDK之前是使用开闭设计模式:对扩展开放,对修改关闭。即:创建一个新的接口,继承原有的接口,定义新的方法
但是这样的话,原本的那些实现类并没有新的方法
这时候可以使用接口默认方法
关键字使用??default??进行修饰, 方法需要方法体。这样的方法所有的子类会默认实现(不用自己写),如果想要覆盖重写,也可以在实现类中覆盖重写
public& nbsp; interface& nbsp; IUserService& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method1();
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method2();

public& nbsp; class& nbsp; IUserImpl& nbsp; implements& nbsp; IUserService& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; @Override
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; method1()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; method1& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Override
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; method2()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; method2& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

public& nbsp; class& nbsp; IUser2Impl& nbsp; implements& nbsp; IUserService& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; @Override
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; method1()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; method1& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Override
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; method2()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; method2& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

在上面的示例中一个接口有两个实现类,假如这时需要在接口当中新增一个功能,该接口的所有实现类都需要实现该接口,这样就很麻烦,这时就可以使用接口默认方法,改造后的接口为
public& nbsp; interface& nbsp; IUserService& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method1();
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method2();

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; methodNew()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 新增的功能& quot; );
& nbsp; & nbsp; & nbsp; & nbsp; ;

进行测试
public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; IUserService& nbsp; user& nbsp; =& nbsp; new& nbsp; IUser2Impl();
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; user.methodNew();
& nbsp; & nbsp; & nbsp; & nbsp;


这个时候假如
这里需要注意的是:这里的default是JDK8新增的关键字,和访问限定修饰符??default??不是一个概念,与switch中的default功能完全不同
与抽象类的不同:抽象类更多的是提供一个模板,子类之间的某个流程大致相同,仅仅是某个步骤可能不一样(模板方法设计模式),这个时候使用抽象类,该步骤定义为抽象方法。而default关键字是用于扩展
接口静态默认方法
/**
  *  @author  :tangyihao
  *  @version  :V1.0
  *  @program  :jdk8
  *  @date  :Created  in  2020/8/12  16:25
  *  @description  :从Java8开始,接口当中允许定义静态方法
  *                                修饰符:static  xxx
  *                                一般类的静态方法用法相同
  */
public& nbsp; interface& nbsp; IAnimal& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method();

& nbsp; & nbsp; & nbsp; & nbsp; static& nbsp; void& nbsp; getUser()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 静态接口方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

接口的静态方法不会被实现类所继承
测试
public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; IAnimal.getUser();
& nbsp; & nbsp; & nbsp; & nbsp;


函数式接口概念函数式接口在Java中是指:有且仅有一个抽象方法的接口
函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导
格式确保接口中有且只有一个抽象方法即可
public  interface  接口名称 
        返回值  方法名称();

????@FunctionalInterface注解
有的注解是在编译期起作用,如@Override注解。而@FunctionalInterface也是在编译期起作用。该注解是Java8专门为函数式接口引入的新的注解,作用于一个接口上。一旦使用该注解来定义接口,编译期会强制检查该接口是否符合函数式接口的条件,不符合则会报错。需要注意的是:即使不使用该注解,只要满足函数式接口的定义,该接口就是一个函数式接口
使用注解
@FunctionalInterface
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method();

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

不使用注解
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method();

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

Lambda表达式【JDK8】在面向对象的基础上,Java8通过Lambda表达式与方法引用等,为开发者打开了函数式编程的大门。Lambda表达式不是语法糖,而是新的语法
语法三要素:参数、箭头、代码
(参数)  ->  
代码

(参数类型 参数1,参数类型 参数2, ....) -> 代码
首先定义函数式接口
@FunctionalInterface
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method(String& nbsp; str);

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

测试
public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMethod((String& nbsp; str)& nbsp; -& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(str);
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; private& nbsp; void& nbsp; getMethod(MyFunctionInterface& nbsp; functionInterface)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; functionInterface.method(& quot; lamdba表达式& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

  1. 如果参数有多个,那么使用逗号分隔。如果参数没有,则留空
@FunctionalInterface
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method();

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMethod(()& nbsp; -& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; private& nbsp; void& nbsp; getMethod(MyFunctionInterface& nbsp; functionInterface)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; functionInterface.method();
& nbsp; & nbsp; & nbsp; & nbsp;

  1. 箭头是固定写法
  2. 大括号相当于方法体
使用Lambda表达式的必要前提:必须是??函数式接口??
Lambda 省略规则
  • 参数类型可以省略。但是只能同时省略所有参数的类型,或者干脆都不省略
@FunctionalInterface
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method(String& nbsp; str,& nbsp; Integer& nbsp; age);

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMethod((str,& nbsp; age)& nbsp; -& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(str& nbsp; +& nbsp; age);
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; private& nbsp; void& nbsp; getMethod(MyFunctionInterface& nbsp; functionInterface)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; functionInterface.method(& quot; BNTang& quot; ,& nbsp; 23);
& nbsp; & nbsp; & nbsp; & nbsp;

  • 如果参数有且仅有一个,那么小括号可以省略
@FunctionalInterface
public& nbsp; interface& nbsp; MyFunctionInterface& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; void& nbsp; method(String& nbsp; str);

& nbsp; & nbsp; & nbsp; & nbsp; default& nbsp; void& nbsp; defaultMethod()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(& quot; 接口默认方法& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMethod(str& nbsp; -& gt; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(str);
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; );
& nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; private& nbsp; void& nbsp; getMethod(MyFunctionInterface& nbsp; functionInterface)& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; functionInterface.method(& quot; BNTang& quot; );
& nbsp; & nbsp; & nbsp; & nbsp;

  • 如果大括号内的语句有且仅有一条,那么无论是否有返回值,return、大括号、分号都可以省略
public& nbsp; class& nbsp; MyTest& nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; @Test
& nbsp; & nbsp; & nbsp; & nbsp; public& nbsp; void& nbsp; test()& nbsp;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; getMethod(str& nbsp; -& gt;
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; System.out.println(str)
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; );
& nbsp; & nbsp;

    推荐阅读