java8新特性总结

虽然java8已经快过期了,但是作为技术总结,还是简单总结一下。

目录

1所谓的java8新特性有哪些

2.java8新特性详解

2.1 lambda表达式

1.概述

2.示例代码

3. Lambda的语法规则

4.函数式接口@FunctionalInterface注解

5. 练习

6.Lambda表达式的使用前提

7.有价值的参考文章

3.接口的增强

3.1. JDK8中接口的新增

3.2 默认方法

1为什么要增加默认方法

2接口默认方法的格式

3 接口中默认方法的使用

3.3. 静态方法

1 语法规则

2 静态方法的使用

3 两者的区别介绍

4.函数式接口

4.1定义

4.2.可看成函数式接口的接口

4.3函数式接口存在的意义

 4.4 常见的几种函数是接口的分类


1所谓的java8新特性有哪些

  1. Lambda表达式

  2. 接口的增强

  3. 函数式接口

  4. 方法引用

  5. Stream API

  6. Optional

  7. 新时间日期API

  8. 其他新特性

2.java8新特性详解

2.1 lambda表达式

1.概述

Java中的Lambda表达式是JDK8中的一种新特性,它允许我们将一段代码(这段代码可以理解为一个接口的实现)当成参数传递给某个方法,然后进行业务处理,这种方式更像是一种函数式编程风格,可以让代码结构更简洁,开发效率更高。

比较让人容易迷乱的是lambda的几个简化写法。后面会一一细说。

lambda的学习点也就两个,一个是把一点代码作为参数传递,一个是它的简化写法。

2.示例代码

  public static void main(String[] args) {
        // 开启一个新的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("新线程中执行的代码 : "+Thread.currentThread().getName());
            }
        }).start();
        System.out.println("主线程中的代码:" + Thread.currentThread().getName());
    }

从这段代码看到,将Runnable接口实现作为一个参数传递,创建了Thread类后,调用了start()。这也是lamnda的核心思想所在。当然在使用中,我们更多的使用在这个基础上的简化写法。

分析上面代码,在创建Thread对象时,其实在乎的作为入参的这段代码的结果,这个结果才是Thread对象创建需要的。换句话说就是这段代码的params和body体。而lambda简化的精髓就在于,只需要关注作为参数的这个代码块的params和body体,其他的编译器会通过底层的类型推断编译时自动补充。(因此能用lanbda的也是一些常用的固定写法:编译器能识别到的写法。事实上必须入参代码块是个函数式接口。

 new Thread(() ->System.out.println("新线程中执行的代码 : "+Thread.currentThread().getName())).start();

上面是简化后的写法。看起来是不是很清爽,因为在作为入参的代码块的组成元素:

访问修饰符

返回值类型

方法名

参数列表

body体

中为只关注了参数列表(没有就用()表示)和body体。

3. Lambda的语法规则

Lambda的标准格式由3个部分组成:

(参数类型 参数名称) -> {
    代码体;
}

格式说明:

  • (参数类型 参数名称):参数列表

  • {代码体;} :方法体

  • -> : 箭头,分割参数列表和方法体

常见结构如下:

 () -> statement

arg -> statement

 (arg1, arg2, ...) -> {  body-block }

(Type1 arg1, Type2 arg2, ...) -> { method-body-block;return value; }

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;
                } );

4.函数式接口

@FunctionalInterface注解

  

/**
 * @FunctionalInterface
 *    这是一个标志注解,被该注解修饰的接口只能声明一个抽象方法
 */
@FunctionalInterface
public interface UserService {

    void show();

}

5. 练习

public interface UserService {
    void show();
}
public class Demo03Lambda {

    public static void main(String[] args) {
        goShow(new UserService() {
            @Override
            public void show() {
                System.out.println("show 方法执行了...");
            }
        });
        System.out.println("----------");
        goShow(() -> { System.out.println("Lambda show 方法执行了..."); });
    }

    public static void goShow(UserService userService){
        userService.show();
    }
}

 输出

show 方法执行了...
----------
Lambda show 方法执行了...

6.Lambda表达式的使用前提

Lambda表达式的语法是非常简洁的,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意

  1. 方法的参数或局部变量类型必须为接口才能使用Lambda

  2. 接口中有且仅有一个抽象方法(@FunctionalInterface)

7.有价值的参考文章

关于Java Lambda表达式看这一篇就够了

3.接口的增强

3.1. JDK8中接口的新增

在JDK8中针对接口有做增强,在JDK8之前

interface 接口名{
    静态常量;
    抽象方法;
}
JDK8之后对接口做了增加,接口中可以有默认方法静态方法

interface 接口名{  

 静态常量;  

 抽象方法;  

 默认方法;  

 静态方法; }

3.2 默认方法

1为什么要增加默认方法

在JDK8以前接口中只能有抽象方法和静态常量,会存在以下的问题:

如果接口中新增抽象方法,那么实现类都必须要抽象这个抽象方法,非常不利于接口的扩展的

package com.bobo.jdk.inter;

public class Demo01Interface {

    public static void main(String[] args) {
        A a = new B();
        A c = new C();
    }
}

interface A{
    void test1();
    // 接口中新增抽象方法,所有实现类都需要重写这个方法,不利于接口的扩展
    void test2();
}

class B implements  A{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }
}

class C implements A{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }
}

2接口默认方法的格式

接口中默认方法的语法格式是

interface 接口名{
    修饰符 default 返回值类型 方法名{
        方法体;
    }
}
package com.bobo.jdk.inter;

public class Demo01Interface {

    public static void main(String[] args) {
        A a = new B();
        a.test3();
        A c = new C();
        c.test3();

    }
}

interface A{
    void test1();
    // 接口中新增抽象方法,所有实现类都需要重写这个方法,不利于接口的扩展
    void test2();

    /**
     * 接口中定义的默认方法
     * @return
     */
    public default String  test3(){
        System.out.println("接口中的默认方法执行了...");
        return "hello";
    }
}

class B implements  A{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }

    @Override
    public String test3() {
        System.out.println("B 实现类中重写了默认方法...");
        return "ok ...";
    }
}

class C implements A{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }
}

3 接口中默认方法的使用

接口中的默认方法有两种使用方式

  1. 实现类直接调用接口的默认方法

  2. 实现类重写接口的默认方法

    换句话说就是,需要用的实现类可以重写或者直接调用,不需要用的实现类,可以不用管接口中的默认方法的存在

3.3. 静态方法

JDK8中为接口新增了静态方法,作用也是为了接口的扩展

1 语法规则

interface 接口名{
    修饰符 static 返回值类型 方法名{
        方法体;
    }
}
package com.bobo.jdk.inter;
​
public class Demo01Interface {
​
    public static void main(String[] args) {
        A a = new B();
        a.test3();
        A c = new C();
        c.test3();
        A.test4();
    }
}
​
interface A{
    void test1();
    // 接口中新增抽象方法,所有实现类都需要重写这个方法,不利于接口的扩展
    void test2();
​
    /**
     * 接口中定义的默认方法
     * @return
     */
    public default String  test3(){
        System.out.println("接口中的默认方法执行了...");
        return "hello";
    }
​
    /**
     * 接口中的静态方法
     * @return
     */
    public static String test4(){
        System.out.println("接口中的静态方法....");
        return "Hello";
    }
}
​
class B implements  A{
    @Override
    public void test1() {
​
    }
​
    @Override
    public void test2() {
​
    }
​
    @Override
    public String test3() {
        System.out.println("B 实现类中重写了默认方法...");
        return "ok ...";
    }
​
}
​
class C implements A{
    @Override
    public void test1() {
​
    }
​
    @Override
    public void test2() {
​
    }
}
​

2 静态方法的使用

接口中的静态方法在实现类中是不能被重写的,调用的话只能通过接口类型来实现: 接口名.静态方法名();

3 两者的区别介绍

  1. 默认方法通过实例调用,静态方法通过接口名调用

  2. 默认方法可以被继承,实现类可以直接调用接口默认方法,也可以重写接口默认方法

  3. 静态方法不能被继承,实现类不能重写接口的静态方法,只能使用接口名调用,专属于接口

4.函数式接口

4.1定义

 当且仅当,一个接口被@FunctionInterface注解,且接口中有且只有一个抽象方法的接口
 注意:

1.一旦被@FunctionInteface注解后,接口中有多个抽象方法就会报错
 2.其他方法:
 * 函数时接口就中的静态方法,默认方法

4.2.可看成函数式接口的接口

 接口没有被@FunctionInterface注解,但是接口中只有一个抽象方法,这种接口也可以堪称函数式接口

4.3函数式接口存在的意义


 配和 lambda表达式 操作


 4.4 常见的几种函数是接口的分类


1 消费性接口: 有入参没有返回值,如 Consumer
2 函数式接口: 有入参,入参在接口方法中计算后返回接口,如 Function
3 判定式样接口: 有入参,返回值是boolean 类型 如 Predicate
4 供给式接口:  无参数,有返回值 ,如 supply

package com.tmooc.interfacedefaultandstaticmethod;
 
import java.sql.SQLOutput;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class FunctionIntefaceDemo {
    public static void main(String[] args) {
        //创建函数式接口实例
        Fun fun = new Fun() {
            @Override
            public void domethod01() {
                System.out.println("函数式接口被成功调用");
            }
        };
        //调用函数式接口中唯一的抽象方法
        fun.domethod01();
        System.out.println("=======================================");
        //================================常见的集中函数式接口类型举例================================
        //消费型接口
        Consumer consumer = new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("消费型接口成功被调用");
        System.out.println("=======================================");
        //函数式接口举例
        Function function = new Function() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        };
        Integer result = function.apply("100");
        System.out.println(result);
        consumer.accept("函数型接口成功被调用");
        System.out.println("=======================================");
        Predicate predicate = new Predicate() {
            @Override
            public boolean test(String s) {
                return false;
            }
        };
        boolean res = predicate.test("测试");
        System.out.println(res);
        System.out.println("判定型接口被成功调用");
        System.out.println("=======================================");
        Supplier supplier = new Supplier() {
            @Override
            public Integer get() {
                return 0;
            }
        };
        Integer ress = supplier.get();
        System.out.println(ress);
        System.out.println("供给型接口被成功调用");
    }
}
 
@FunctionalInterface
interface Fun {
    //函数式接口中的唯一抽象方法
    void domethod01();
 
    //其他的都是一个或多个静态方法或则默认方法
    static int domethod2() {
        return 1;
    }
 
    default void domethod03() {
    }
}

你可能感兴趣的:(#,java8新特性,java)