当前位置: 代码迷 >> 综合 >> - Java8 新特性
  详细解决方案

- Java8 新特性

热度:16   发布时间:2023-11-18 11:50:35.0

文章目录

      • 接口默认实现
      • 函数式接口
      • Lambda 表达式
      • 双冒号`::`

接口默认实现

若要修改接口,比如给接口添加一个抽象方法,那就得修改所有实现了该接口的实现类;麻烦!

接口里面可以有默认实现,就是在方法声明上使用default关键字,实现这个接口的类,可以不再实现这个默认实现的方法了;

interface A{
    default String getName(){
    return "zxj";}public abstract show();
}

默认方法冲突:
1、若一个接口B继承自另一个接口A,两个接口中有同样的默认实现方法,那么只保留父接口中的默认方法;

2、若一个类实现两个接口,两个接口有相同的方法,一个接口默认实现了这个方法,那么另一个方法不管是默认实现,还是让它以抽象方法的形式存在,编译都会报错,我们需要在实现类上重写接口的默认方法,或实现抽象方法;

3、一个类继承了类A、实现的接口B,父类A中有一个方法和接口B中的默认实现方法冲突了,根据类优先原则,会使用父类的方法;


函数式接口

函数式接口有且只有一个抽象方法,接口定义上使用@FunctionalInterface注解来标注接口只有一个抽象方法;

Function/BiFunctionConsumer/BiConsumer

Bi**方法里面接收两个参数,第一个参数是用来接收对象实例的,使用对象实例调用第二个参数的非静态方法;

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}
@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);
}
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}
@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u);  // T接收的是对象
}

Lambda 表达式

Lambda表达式,也称为闭包,允许把函数作为一个方法的参数进行传递;

lambda表达式需要用一个接口类型的引用来接收,Lambda表达式方法体其实就是函数式接口的实现;然后将接口类型的引用作为参数传入方法;

语法格式函数式接口类型的引用 = (参数) -> 表达式(参数) -> {代码块}

(参数是函数式接口里面的方法的参数;)

  • 可选类型声明:不用声明参数的类型;
  • 可选参数圆括号:参数是一个的时候不用写圆括号,参数有多个的时候,要加上圆括号;不需要传参的时候直接写一对小括号;
  • 可选大括号:主体只有一个语句,不用使用大括号,主体有多条语句,需要使用大括号括起来;
  • 可选返回关键字:若主体只有一个表达式语句,没有使用大括号,则不需要写返回值,编译器会自动返回;若使用了大括号,需要指定表达式返回了一个数值;

Lambda表达式可以替代内部类;

public class Test {
    public static void main(String[] args) {
    runThreadByLambda();runThreadByInnerClass();}public static void runThreadByLambda() {
    // Runnable就是一个函数式接口:他只有一个方法run()方法。// 1、因为run()方法没有参数,所以 ->前面的()中不需要声明形参;// 2、run返回的是void,所以不需要return;// 3、->后面写的代码其实就是定义在run方法内的代码;因为此处代码只有一行,所以{}也可以省略;Runnable runnable = () -> System.out.println("这个是用Lambda表达式实现的线程");new Thread(runnable).start();  // 将引用变量runnable作为参数传入方法;}public static void runThreadByInnerClass() {
    Runnable runnable = new Runnable() {
       // 匿名内部类;@Overridepublic void run() {
    System.out.println("这个是用内部类实现的线程");}};new Thread(runnable).start();}
}

双冒号::

Lambda表达式的简写形式:引用的方法,就是Lambda表达式的方法体实现;

闭包:就是能够读取函数内部变量的函数,可以理解为一个函数内部的函数,它是函数内部与函数外部连接的桥梁;

Java中的闭包有:内部类、局部内部类、匿名内部类;

类名::方法名,相当于对这个方法闭包的引用;使用双冒号可以访问类的构造方法、普通方法、静态方法;

(1)需要创建一个接口来接收这个引用;这个接口有且只有一个抽象方法,使用@FunctionalInterface注解来标注接口只有一个抽象方法;

@FunctionalInterface
interface MyConvert1<F, T>{
    T convert(F form);
}
@FunctionalInterface
interface MyConvert2<T>{
    void convert(F form);
}

也可以使用Java8新提供的函数式接口Function/BiFunction、Consumer/BiConsumer;

public class Test {
    public static void main(String args[]) throws Exception {
    Consumer<String> printStrConsumer = DoubleColon::printStr;printStrConsumer.accept("printStrConsumer");Consumer<DoubleColon> toUpperConsumer = DoubleColon::toUpper;toUpperConsumer.accept(new DoubleColon());BiConsumer<DoubleColon, String> toLowerConsumer = DoubleColon::toLower;toLowerConsumer.accept(new DoubleColon(), "toLowerConsumer");BiFunction<DoubleColon, String, Integer> toIntFunction = DoubleColon::toInt;int i = toIntFunction.apply(new DoubleColon(), "toInt");}
}
class DoubleColon {
    public static void printStr(String str) {
    System.out.println("static : " + str);}public void toUpper() {
    System.out.println("toUpper : " + this.toString());}public void toLower(String str) {
    System.out.println("toLower : " + str);}public int toInt(String str) {
    System.out.println("toInt : " + str);return 1;}
}

一般方法的引用格式:

  • 如果是静态方法,则是ClassName::methodName。如 Object ::equals
  • 如果是实例方法,则是Instance::methodName。如Object obj=new Object();obj::equals;
  • 构造函数.则是ClassName::new
public class Demo2 {
    public static void main(String[] args) {
    Runnable runnable = Demo2::run;new Thread(runnable).start();}public static void run(){
    System.out.println("方法引用的代码...");}
} 

https://blog.csdn.net/qq_35805528/article/details/53264301

Java语法糖系列五:内部类和闭包:https://www.jianshu.com/p/f55b11a4cec2

双冒号:https://blog.csdn.net/xvhongliang/article/details/84311887
https://blog.csdn.net/kegaofei/article/details/80582356

  相关解决方案