JAVA8特性之函数式接口-@FunctionalInterface注解

颜嘉誉
2023-12-01

函数式接口:

定义:

就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,总体有点像匿名类

@FunctionalInterface:

该注解可加可不加,它是函数式接口语法检查注解的,当然最好是加上,毕竟你加上之后,代码的规范和可读性明显提高了.

详解:

通常我们写一个接口大致如下:

public interface Animal {
    
    void eat();
    
    void say();
    
    void run();
}

实现如下:

/**
 * 实现类 :Dog, 子类要全部实现父接口的全部抽象方法
 */
public class Dog implements Animal {

    @Override
    public void eat() {
        System.out.println("Dog eat");
    }

    @Override
    public void say() {
        System.out.println("Dog say");
    }

    @Override
    public void run() {
        System.out.println("Dog run");
    }
}

应用如下:

@SpringBootTest
class DemoApplicationTests {

    @Test
    public void testFunctionInterface(){
        Animal animal = new Dog();
        animal.say();
        animal.run();
        animal.eat();
    }
}
输出:
Dog say
Dog run
Dog eat

按照上面函数式接口的定义:接口中我们只保留一个抽象方法,
场景如下:

/**
 * 只有一个抽象方法eat所以就满足是个函数式接口
 */
public interface Animal {

    void eat();

    /**
     * 默认方法:子类可以也可以继承或者重写,
     */
    default void say() {
        System.out.println("Animal say");
    };

    /**
     * 子类不可继承,接口直接调用
     */
    static void run() {
        System.out.println("Animal run");
    };
}

/**
 * 实现类Cat
 */
public class Cat implements Animal {

    @Override
    public void eat() {
        System.out.println("Cat eat");
    }
}

应用:

@SpringBootTest
class DemoApplicationTests {

    @Test
    public void testFunctionInterface(){

        /**
         * 函数式接口应用场景一
         */
        // 直接调用接口中的静态方法
        Animal.run();

        // 相当于定义了Animal的唯一的一个抽象方法(eat)中的实现
        Animal animal = () -> System.out.println("Lambda表达式实现的eat");
        animal.eat();

        // 执行默认方法
        animal.say();

        /**
         * 函数式接口应用场景二
         */
        Animal cat = new Cat();

        // 执行子类重写的say方法
        cat.say();

        // 子类常规实现父接口中的eat方法
        cat.eat();

        /**
         * 函数式接口应用场景三
         */
        fead(() -> System.out.println("fead方法入参"));
    }

    public void fead(Animal animal) {

        // 调用函数式接口中的抽象方法
        animal.eat();
    }
}
输出结果:
Animal run
Lambda表达式实现的eat
Animal say
Animal say
Cat eat
fead方法入参

函数式接口应用场景二和三中, 其实我们可以看出,那个Lambda表达式其实就相当于一个方法的方法体,也就是说是一个方法的实现, 这也是为什么函数式接口中要求只能有一个抽象方法,这样的话, 无论是 () -> System.out.println(“Lambda表达式实现的eat”)还是 () -> System.out.println(“fead方法入参”) 都相当于那个方法的实现,相当于冥冥中就创建了一个函数式接口的匿名实现类.

常见的函数式接口

在包java.util.function下面有很多函数式接口, 函数式接口使用的最典型最广泛的地方也就是java8的Lambda表达式,可以详细看一下Lambda表达式的入参类型就知道了.

 类似资料: