JDK8

Posted qq628b229e2808e

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK8相关的知识,希望对你有一定的参考价值。

介绍

随着java的发展,越来越多的企业开始使用​​java8​​版本。Java8是自从java5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。

????JDK8新增的特性如下

  • Lambda表达式
  • 新的日期API、Datetime
  • 引入Optional防止空指针异常
  • 使用Base64
  • 接口的默认方法和静态方法
  • 新增方法引用格式
  • 新增Stream类
  • 注解相关的改变
  • 支持并行(parallel)数组
  • 对并发类(Concurrency)的扩展
  • JavaFX

接口新特性

接口默认方法

当我们去实现某个框架提供的一个接口时,需要实现其所有的抽象方法,当该框架更新版本,在这个借口中加入了新的抽象方法时,我们就需要对项目重新编译,并且实现其新增的方法。当实现类太多时,操作起来很麻烦

JDK之前是使用开闭设计模式:对扩展开放,对修改关闭。即:创建一个新的接口,继承原有的接口,定义新的方法

但是这样的话,原本的那些实现类并没有新的方法

这时候可以使用接口默认方法

关键字使用​​default​​进行修饰, 方法需要方法体。这样的方法所有的子类会默认实现(不用自己写),如果想要覆盖重写,也可以在实现类中覆盖重写

public interface IUserService 
    void method1();
    void method2();
public class IUserImpl implements IUserService 
    @Override
    public void method1() 
        System.out.println("method1");
    

    @Override
    public void method2() 
        System.out.println("method2");
    
public class IUser2Impl implements IUserService 
    @Override
    public void method1() 
        System.out.println("method1");
    

    @Override
    public void method2() 
        System.out.println("method2");
    

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

public interface IUserService 
    void method1();
    void method2();

    default void methodNew()
        System.out.println("新增的功能");
    ;

进行测试

public class MyTest 

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

这个时候假如

这里需要注意的是:这里的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 interface IAnimal 
    void method();

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

接口的静态方法不会被实现类所继承

测试

public class MyTest 

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

函数式接口

概念

函数式接口在Java中是指:有且仅有一个抽象方法的接口

函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导

格式

确保接口中有且只有一个抽象方法即可

public interface 接口名称 
    返回值 方法名称();

????@FunctionalInterface注解

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

使用注解

@FunctionalInterface
public interface MyFunctionInterface 
    void method();

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

不使用注解

public interface MyFunctionInterface 
    void method();

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

Lambda表达式

在面向对象的基础上,Java8通过Lambda表达式与方法引用等,为开发者打开了函数式编程的大门。Lambda表达式不是语法糖,而是新的语法

语法

三要素:参数、箭头、代码

(参数) -> 
代码

(参数类型 参数1, 参数类型 参数2, ....) -> 代码

首先定义函数式接口

@FunctionalInterface
public interface MyFunctionInterface 
    void method(String str);

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

测试

public class MyTest 

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

    private void getMethod(MyFunctionInterface functionInterface) 
        functionInterface.method("lamdba表达式");
    
  1. 如果参数有多个,那么使用逗号分隔。如果参数没有,则留空
@FunctionalInterface
public interface MyFunctionInterface 
    void method();

    default void defaultMethod() 
        System.out.println("接口默认方法");
    
public class MyTest 

    @Test
    public void test() 
        getMethod(() -> 
        );
    

    private void getMethod(MyFunctionInterface functionInterface) 
        functionInterface.method();
    
  1. 箭头是固定写法
  2. 大括号相当于方法体

使用Lambda表达式的必要前提:必须是​​函数式接口​

Lambda 省略规则

  • 参数类型可以省略。但是只能同时省略所有参数的类型,或者干脆都不省略
@FunctionalInterface
public interface MyFunctionInterface 
    void method(String str, Integer age);

    default void defaultMethod() 
        System.out.println("接口默认方法");
    
public class MyTest 

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

    private void getMethod(MyFunctionInterface functionInterface) 
        functionInterface.method("BNTang", 23);
    
  • 如果参数有且仅有一个,那么小括号可以省略
@FunctionalInterface
public interface MyFunctionInterface 
    void method(String str);

    default void defaultMethod() 
        System.out.println("接口默认方法");
    
public class MyTest 

    @Test
    public void test() 
        getMethod(str -> 
            System.out.println(str);
        );
    

    private void getMethod(MyFunctionInterface functionInterface) 
        functionInterface.method("BNTang");
    
  • 如果大括号内的语句有且仅有一条,那么无论是否有返回值,return、大括号、分号都可以省略
public class MyTest 

    @Test
    public void test() 
        getMethod(str ->
                System.out.println(str)
        );
  以上是关于JDK8的主要内容,如果未能解决你的问题,请参考以下文章

jdk8新特性-Stream流详解及使用样例

jdk8源码Arrays.sort插入排序,居然还可以成对插入

jdk8源码Arrays.sort插入排序,居然还可以成对插入

开场舞蹈 #普及组#

什么?接口中方法可以不是抽象的「JDK8接口新语法的深度思考」

jdk8新特性-Stream流详解及使用样例(Stream创建使用收集并行流注意事项)