首页 > 编程语言 >Java方法引用和构造器引用详细解释

Java方法引用和构造器引用详细解释

时间:2022-11-26 10:35:02浏览次数:28  
标签:逻辑 Java 构造 引用 return 方法 public lambda

1 什么是方法/构造器引用

简单来说,方法引用是对lambda表达式的一种更加简便的写法。

所谓引用,就是对当前已存在的一段代码的借用。

方法引用则是隐式借用已经存在的方法作为现成的执行逻辑,而不必在lambda表达式中显示调用该方法,或者重写这一部分代码

同理,构造器引用则是隐式借用某个类的构造函数创建对象的执行逻辑。

2 举个简单的例子

假设有以下方法,它接收一个泛型参数t,然后使用Comsumer函数式接口进行动态处理:

public class FI1 {
    public static <T> void accept(T t, Consumer<T> consumer) {
        consumer.accept(t);
    }
}

假如,我们只需要简单打印一个字符串,可以按照如下方式进行显示调用引用的println()方法:

FI1.accept("Xianhuii", t -> {
    System.out.println(t);
});

或者按照如下方式进行重写代码

FI1.accept("Xianhuii", t -> {
    PrintStream out = System.out;
    synchronized (out) {
        out.print(t);
        out.print("\n\b");
    }
});

我们可以查看Consumer#accept方法的格式:

void accept(T t);

以及System.out.println()方法的格式:

public void println(String x) {}

发现它俩的形参数量和返回值类型都一致。同时,我们需要的业务逻辑与println()方法定义的一致。

因此,我们可以直接引用该方法:

FI1.accept("Xianhuii", System.out::println);

相当于将System.out.println(String)方法等价替换了accept(T)方法,并使用了现有的执行逻辑。

3 方法引用的格式

方法引用可以分成三种情况:

  1. 对象::实例方法
  2. 类::静态方法
  3. 类::实例方法

这三种情况也分别对应着不同格式(形参和返回值)的lambda表达式/函数式接口方法。

但是我们需要注意:任何情况下,被引用方法的执行逻辑必须与lambda表达式中的执行逻辑一致。

3.1 对象::实例方法

对象::实例方法引用的是对象的方法,::前表示被引用的对象,::后表示被引用对象的实例方法。

3.1.1 Consumer<T>

函数式接口:

public interface Consumer<T> {
    void accept(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
}

方法引用:

obj::accetp

被引用方法:

public void accept(T t) {
    // 相同的业务逻辑
}

3.1.2 Function<T, R>

函数式接口:

public interface Function<T, R> {
    R apply(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return r;
}

方法引用:

obj::apply

被引用方法:

public R apply(T t) {
    // 相同的业务逻辑
    return r;
}

3.1.3 Supplier<T>

函数式接口:

public interface Supplier<T> {
    T get();
}

lambda表达式:

() -> {
    // 相同的业务逻辑
    return t;
}

方法引用:

obj::get

被引用的方法:

public T get() {
    // 相同的业务逻辑
    return t;
}

3.1.4 Predicate<T>

函数式接口:

public interface Predicate<T> {
    boolean test(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return flag;
}

方法引用:

obj::test

被引用的方法:

public boolean test(T t) {
    // 相同的业务逻辑
    return flag;
}

3.2 类::静态方法

类::静态方法引用的是类的静态方法,::前表示被引用的类,::后表示被引用类的静态方法。

类::静态方法的转换方式与对象::实例方法相同,只是引用对象和引用方法有所区别。

3.2.1 Consumer<T>

函数式接口:

public interface Consumer<T> {
    void accept(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
}

方法引用:

Clz::accetp

被引用方法:

public static void accept(T t) {
    // 相同的业务逻辑
}

3.2.2 Function<T, R>

函数式接口:

public interface Function<T, R> {
    R apply(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return r;
}

方法引用:

Clz::apply

被引用方法:

public static R apply(T t) {
    // 相同的业务逻辑
    return r;
}

3.2.3 Supplier<T>

函数式接口:

public interface Supplier<T> {
    T get();
}

lambda表达式:

() -> {
    // 相同的业务逻辑
    return t;
}

方法引用:

Clz::get

被引用的方法:

public static T get() {
    // 相同的业务逻辑
    return t;
}

3.2.4 Predicate<T>

函数式接口:

public interface Predicate<T> {
    boolean test(T t);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return flag;
}

方法引用:

Clz::test

被引用的方法:

public static boolean test(T t) {
    // 相同的业务逻辑
    return flag;
}

3.3 类::实例方法

类::实例方法本质上引用的是对象的实例方法,只是对象是lambda表达式的第一个形参。

::前表示被引用对象所属的类,::后表示被引用对象的实例方法。

3.3.1 Consumer<T>

函数式接口:

public interface Consumer<T> {
    void accept(T t, P p);
}

lambda表达式:

(t) -> {
    t.fun(p);
}

方法引用:

Clz::fun

被引用方法:

public void fun(P p) {
    // 相同的业务逻辑
}

3.3.2 Function<T, R>

函数式接口:

public interface Function<T, R> {
    R apply(T t, P p);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return t.fun(p);
}

方法引用:

Clz::fun

被引用方法:

public static R fun(P p) {
    // 相同的业务逻辑
    return r;
}

3.3.3 Supplier<T>

函数式接口:

public interface Supplier<T> {
    R get(T t);
}

lambda表达式:

() -> {
    // 相同的业务逻辑
    return t.fun();
}

方法引用:

Clz::fun

被引用的方法:

public static R fun() {
    // 相同的业务逻辑
    return r;
}

3.3.4 Predicate<T>

函数式接口:

public interface Predicate<T> {
    boolean test(T t, P p);
}

lambda表达式:

(t) -> {
    // 相同的业务逻辑
    return t.fun(p);
}

方法引用:

Clz::fun

被引用的方法:

public static boolean fun(P p) {
    // 相同的业务逻辑
    return flag;
}

4 构造器引用的格式

构造器引用可以是一种特殊的类::静态方法引用,只不过这里的静态方法是构造函数

构造器引用的格式为:类::new

lambda表达式/函数式接口的形参,对应构造函数的形参。并且编译器会根据形参的个数和类型,推断出正确的构造函数进行引用。

由于构造函数一定会返回实例对象,所以对应lambda表达式也必须有返回值。

4.1 类::new

4.1.1 Function<T, R>

函数式接口:

public interface Function<T, R> {
    R apply(T t);
}

lambda表达式:

(t) -> {
    return new Date(t);
}

方法引用:

Date::new

被引用方法:

public Date(long date) {
    fastTime = date;
}

4.1.2 Supplier<T>

函数式接口:

public interface Supplier<T> {
    R get();
}

lambda表达式:

() -> {
    return new Date();
}

方法引用:

Date::new

被引用的方法:

public Date() {
    this(System.currentTimeMillis());
}

4.2 类[]::new

如果需要创建数组对象,可以引用数组的构造函数。

需要注意的是,此时必须传入一个参数,作为数组的长度。

此外,这种方式无法为每个值赋值,因此最终得到的数组值都为null

4.1.1 Function<T, R>

函数式接口:

public interface Function<T, R> {
    R apply(T t);
}

lambda表达式:

(t) -> {
    return new Date[t];
}

方法引用:

Date[]::new

被引用方法:

new Date[t];

标签:逻辑,Java,构造,引用,return,方法,public,lambda
From: https://www.cnblogs.com/Xianhuii/p/16927010.html

相关文章

  • 小新学Java11
    一、异常1.1异常概念异常︰指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常......
  • 为什么要使用Java Stream API?
    Stream是Java8提供的一种更加简便的,对集合类型数据结构的处理API。这里的集合类型数据结构包括各种数组(int[]/String[]等),也包括Collection和Map等实现类。1传统方式操作......
  • 深入剖析Java Stream底层源码
    1Stream的使用在深入学习Stream的本质之前,我们需要先熟悉Stream的使用规则。对Stream有了整体的认识之后,才能更好的理解它的本质。1.1使用步骤使用Stream只需要遵循3......
  • Java.11.26
    一1..breakcontinue1.1.break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switc......
  • java使用Jsch/ssh2实现从linux服务端遍历文件名以及文件内容回显到客户端
    java使用Jsch/ssh2实现从linux服务端遍历文件名以及文件内容回显到客户端这里只我上传的是测试类,需改下参数直接用就行。jsch依赖: <dependency>            ......
  • Java connect to SSH2
    GanymedSSH-2(ch.ethz.ssh2)爱码者于 2020-09-2111:17:18 发布6102 收藏 10分类专栏: 项目实践版权 项目实践专栏收录该内容15篇文章0订阅订阅......
  • java简单解析wsdl文件
    1packagecom.example.demo.api.soap.client.userInterface.controller;234importorg.w3c.dom.Document;5importorg.w3c.dom.NamedNodeMap;6importor......
  • Java JDK11的下载与安装
    前言本篇文章是基于win10系统下载安装JDK11的教程。1.下载OracleJDK进入Oracle官网:https://www.oracle.com/java/technologies/downloads/#java11选择Java11→Winodws→......
  • Java8新特性
    Java8NashornJavaScriptJava8新特性Java8新特性Nashorn一个javascript引擎。NashornJavaScriptEngine在Java15已经不可用了。这已经在Java11标记为:@de......
  • 重点--微信公众号(事件回调&生成带参数二维码&扫码关注事件&消息模板推送)java版
     1.业务处理(全部业务)importcom.alibaba.fastjson.JSONObject;importorg.springframework.util.StringUtils;importorg.springframework.web.bind.annotation.*;impo......