当前位置: 首页 > news >正文

Java 方法引用(Method Reference)从入门到精通

方法引用概述

方法引用(Method Reference)是 Java 8 引入的一种简洁的 Lambda 表达式写法。它允许我们直接引用已有的方法,而不必重复实现 Lambda 代码,使代码更加简洁、可读性更强。

方法引用的基本语法如下:

类名::静态方法名
对象名::实例方法名
类名::实例方法名
类名::new  // 构造方法引用

主要类型

  1. 引用静态方法
  2. 引用特定对象的实例方法//   需要形参和返回值类型一样
  3. 引用某个类的任意对象的实例方法
  4. 引用构造方法
  5. 引用数组的构造方法

注意事项:

  • 方法引用的目标必须是 函数式接口(Functional Interface),即仅包含一个抽象方法的接口,如 Supplier<T>, Function<T, R>, Consumer<T> 等。
  • 方法签名必须匹配 Lambda 表达式 的参数和返回类型。
  • 方法引用不会改变方法的执行方式,只是简化 Lambda 代码。

1. 引用静态方法

静态方法可以被方法引用直接调用,适用于方法签名匹配的情况。

示例:

import java.util.function.Function;

public class StaticMethodReference {
    public static int square(int num) {
        return num * num;
    }
    
    public static void main(String[] args) {
        Function<Integer, Integer> function = StaticMethodReference::square;
        System.out.println(function.apply(5));  // 输出 25
    }
}

注意事项:

  • 被引用的方法必须是 static,否则无法使用 类名::方法名 方式引用。
  • Lambda 需要的参数列表和返回值必须匹配方法签名。

2. 引用其他类的成员方法

当一个对象的实例方法符合 Lambda 预期参数类型时,可以引用该对象的方法。

示例:

import java.util.function.Supplier;

public class InstanceMethodReference {
    public String getMessage() {
        return "Hello, Method Reference!";
    }
    
    public static void main(String[] args) {
        InstanceMethodReference instance = new InstanceMethodReference();
        Supplier<String> supplier = instance::getMessage;
        System.out.println(supplier.get());  // 输出 "Hello, Method Reference!"
    }
}

注意事项:

  • instance::methodName 只能用于方法不带参数或参数匹配函数式接口的情况。
  • 适用于 Supplier<T>Consumer<T> 这类接口。

3. 引用本类或者父类的成员方法

如果方法在本类或父类中,可以直接用 thissuper 进行方法引用。

示例(本类方法):

import java.util.function.Function;

public class ThisMethodReference {
    public int doubleValue(int num) {
        return num * 2;
    }
    
    public void execute() {
        Function<Integer, Integer> function = this::doubleValue;
        System.out.println(function.apply(10));  // 输出 20
    }
    
    public static void main(String[] args) {
        new ThisMethodReference().execute();
    }
}

示例(父类方法):

class Parent {
    public void greet() {
        System.out.println("Hello from Parent");
    }
}

public class SuperMethodReference extends Parent {
    public void execute() {
        Runnable r = super::greet;
        r.run();  // 输出 "Hello from Parent"
    }
    
    public static void main(String[] args) {
        new SuperMethodReference().execute();
    }
}

注意事项:

  • 适用于 this::methodNamesuper::methodName
  • 适用于 RunnableConsumer<T> 等无参方法。
  • 静态方法中没有this、super等关键字

4. 引用类名的成员方法

如果 Lambda 表达式的第一个参数是调用方法的对象,则可以使用 类名::实例方法 形式。

示例:

import java.util.Arrays;
import java.util.List;

public class ClassNameMethodReference {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        list.forEach(System.out::println);  // 逐行打印字符串
    }
}

注意事项:

  • 适用于 Consumer<T>Function<T, R> 等。
  • 类名::方法名 形式适用于 list.forEach(System.out::println) 这种情况。

5. 引用构造方法

构造方法可以用 类名::new 进行引用。

示例:

import java.util.function.Supplier;

class User {
    public User() {
        System.out.println("User created");
    }
}

public class ConstructorReference {
    public static void main(String[] args) {
        Supplier<User> supplier = User::new;
        User user = supplier.get();  // 输出 "User created"
    }
}

注意事项:

  • 适用于 Supplier<T>(无参数构造)。
  • 适用于 Function<T, R>(有参数构造)。

6. 引用数组的构造方法

数组构造方法可以使用 类型[]::new 进行引用。

示例:

import java.util.function.IntFunction;

public class ArrayConstructorReference {
    public static void main(String[] args) {
        IntFunction<int[]> arraySupplier = int[]::new;
        int[] arr = arraySupplier.apply(5);
        System.out.println("Array length: " + arr.length);  // 输出 "Array length: 5"
    }
}

注意事项:

  • 适用于 IntFunction<T[]> 形式。
  • 可以用于创建 int[]::newString[]::new 等。

结论

方法引用是 Lambda 表达式的简洁替代方案,使代码更具可读性。主要掌握以下几种方法引用:

  1. 类名::静态方法 引用静态方法。
  2. 对象::实例方法 引用特定对象的实例方法。
  3. 类名::实例方法 引用某个类的任意对象的实例方法。
  4. 类名::new 引用构造方法。
  5. 类型[]::new 引用数组构造方法。

关键点:

  • 适用于函数式接口。
  • 方法签名必须匹配。
  • 方法引用不会改变方法执行逻辑。

相关文章:

  • 工作记录 2017-01-12
  • vue3 + css 列表无限循环滚动+鼠标移入停止滚动+移出继续滚动
  • 开源:LMDB 操作工具:lmcmd
  • 【万字总结】构建现代Web应用的全方位性能优化体系学习指南(一)
  • 基于Hadoop的城市道路交通数据的可视化分析-Flask
  • SAP ABAP BDC 录屏开发
  • spring boot实现程序运行过程中数据源动态切换
  • STM32配套程序接线图
  • WPF程序使用AutoUpdate实现自动更新
  • 重学vue3(二):vue3生命周期(包含父与子)
  • 专家系统如何运用谓词逻辑进行更复杂的推理
  • 模版题目的集合
  • maven--依赖的搜索顺序
  • 游戏引擎学习第158天
  • MySQL(第四周)
  • 整本书测试与巩固_《C++并发编程实战》笔记
  • C# 使用Markdown2Pdf把md文件转换为pdf文件
  • Flutter网页交互增强插件pulse_core_web的使用
  • “全志V821:智能玩具的理想之选”——科技赋能,乐趣升级
  • JVM调优关注的核心指标?
  • 网站的栏目和板块/竞价代运营
  • 东莞网站优化的具体方案/哈尔滨seo网络推广
  • 上海平台网站建设/竞价运营是做什么的
  • 柳州学校网站建设/比较好网站制作公司
  • 怎么检查网站的死链/搜索网站
  • 服务型网站建设/潮州seo