对于Java 中 Consumer 和函数式接口机制的疑问?

我是一个Java初学者
对于Consumer和函数式接口机制我感到不理解。

这是其接口的部分源码:

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    // ....
}

假设我现在有一个测试方法来使用:

@Test
public static void testConsumer(){
        Consumer<Integer> square = x -> System.out.println("print square : " + x * x);
        square.accept(2);
    }

我不理解的是 这个系统自带的函数式接口,我并没有去“实现”它的逻辑,可是当使用accept方法传参时,在Lambda表达式中的x却能接受到accept提供的值,就好像在哪里回调了一样,但我事实上并没有对accept方法做任何的实现,这是怎么回事呢?

阅读 3.5k
5 个回答

Java接口里只有一个抽象方法时,这个接口是函数式接口。比如注解@FunctionalInterface也定义了这是一个函数式接口。Consumer是典型的函数式接口。
那么你在Test中的代码实际上就把函数式接口隐式转换成了一个Lambda表达式来实现。
具体在编译时编译器会根据Lambda规范判断形参是否满足函数式接口里面唯一抽象方法的定义,满足则编译通过,会正常推导Lambda表达式。

这是 Java 语言中对 SAM 类型的一种语法糖,如果你要继承的抽象类或者接口只包含一个必须要实现的方法,那么你可以直接用 lambda 表达式进行赋值

建议你去搜索一下 Java 8 函数式接口。

Java 的 Lambda 本质是用接口实现的,就是只有一个方法接口的接口

Consumer<Integer> square = x -> System.out.println("print square : " + x * x);

相当于

public class IntegerConsumerImpl<Integer> implements Consumer<Integer>{
    void accept(Integer x) {
        System.out.println("print square : " + x * x);
    }
}
Consumer<Integer> square = new IntegerConsumerImpl<>();

编译器简化了代码

.

Consumer<Integer> square = x -> System.out.println("print square : " + x * x);
square.accept(2);

其中System.out.println("print square : " + x * x) 就是你对accpet方法的实现
然后square.accept(2)你又调用了你的实现

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题