【Java 8】方法引用

方法引用 是 Java 8 中引入的一种简洁语法,可以用来代替某些特定的 Lambda 表达式。简单来说,方法引用是直接使用已有的方法来实现功能,而不必显式地写出方法的具体实现过程。

方法引用使用::符号来表示。


在 Java中,方法引用主要分为四种类型:

        • [1. 静态方法引用](#1. 静态方法引用)
        • [2. 实例方法引用](#2. 实例方法引用)
        • [3. 特定类型的任意对象的方法引用](#3. 特定类型的任意对象的方法引用)
        • [4. 构造器引用](#4. 构造器引用)

举个简单的例子------假设我们有一组姓名待打印。可以使用 Lambda 表达式或方法引用来实现:

  • 使用Lambda表达式:

    java 复制代码
    names.forEach(name -> System.out.println(name));

    这里的name -> System.out.println(name)就是一个简单的Lambda表达式,它的功能是接收每个名字,然后打印它。

  • 使用方法引用:

    java 复制代码
    names.forEach(System.out::println);

    这里System.out::println就是方法引用,直接指向了println方法的功能。这比前面的Lambda表达式更简洁直观。


1. 静态方法引用

静态方法引用的格式是:ClassName::staticMethodName,用来引用某个类的静态方法。

示例

Math类里面有一个静态方法abs(),用于求一个整数的绝对值。

java 复制代码
import java.util.function.Function;

public class StaticMethodExample {
    public static void main(String[] args) {
        // 使用 Lambda 表达式
        Function<Integer, Integer> lambdaAbs = (x) -> Math.abs(x);
        
        // 使用静态方法引用
        Function<Integer, Integer> methodRefAbs = Math::abs;

        System.out.println(lambdaAbs.apply(-10));  // 输出 10
        System.out.println(methodRefAbs.apply(-20));  // 输出 20
    }
}

在这里,Math::abs是对Math.abs静态方法的引用,它的作用是接收一个整数并返回它的绝对值。


2. 实例方法引用

实例方法引用的格式是:instance::methodName,用来引用某个对象的实例方法。

示例

想要得到一个字符串的长度:

java 复制代码
import java.util.function.Supplier;

public class InstanceMethodExample {
    public static void main(String[] args) {
        String message = "Hello, world!";
        
        // 使用 Lambda 表达式
        Supplier<Integer> lambdaLength = () -> message.length();
        
        // 使用实例方法引用
        Supplier<Integer> methodRefLength = message::length;

        System.out.println(lambdaLength.get());  // 输出 13
        System.out.println(methodRefLength.get());  // 输出 13
    }
}

在这个例子中,message::length引用了message字符串的length()方法,用来获取字符串的长度。


3. 特定类型的任意对象的方法引用

特定类型的任意对象的方法引用的格式是:ClassName::methodName,用于引用某个类的实例方法,但不指定具体的对象。它通常用于集合操作,适用于所有该类的对象。

示例

有一个包含若干字符串的列表,想要把每个字符串转换为大写字母。

java 复制代码
import java.util.Arrays;
import java.util.List;

public class ArbitraryObjectExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("alice", "bob", "charlie");

        // 使用 Lambda 表达式
        names.forEach(name -> System.out.println(name.toUpperCase()));
        
        // 使用特定类型的任意对象的方法引用
        names.forEach(String::toUpperCase);
    }
}

在这个例子中,String::toUpperCase表示的是对于每个字符串都调用toUpperCase()方法。实际上,这里的方法引用就相当于对列表中的每个字符串进行统一的转换操作。


4. 构造器引用

构造器引用的格式是:ClassName::new,用于引用类的构造方法。这样我们可以通过工厂模式轻松地创建对象。

示例

我们有一个Person类,它有一个无参构造器。使用构造器引用来创建新的Person对象。

java 复制代码
import java.util.function.Supplier;

public class ConstructorReferenceExample {
    public static void main(String[] args) {
        // 使用 Lambda 表达式
        Supplier<Person> lambdaPerson = () -> new Person();
        
        // 使用构造器引用
        Supplier<Person> methodRefPerson = Person::new;

        Person p1 = lambdaPerson.get();
        Person p2 = methodRefPerson.get();

        System.out.println(p1);  // 输出 Person{name='Unknown'}
        System.out.println(p2);  // 输出 Person{name='Unknown'}
    }
}

class Person {
    String name;

    public Person() {
        this.name = "Unknown";
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
}

在这里,Person::new是对Person类构造器的引用,它的作用是创建一个新的Person对象。

相关推荐
小尤笔记7 分钟前
利用Python编写简单登录系统
开发语言·python·数据分析·python基础
飞升不如收破烂~9 分钟前
Spring boot常用注解和作用
java·spring boot·后端
秦老师Q10 分钟前
Java基础第九章-Java集合框架(超详细)!!!
java·开发语言
计算机毕设源码qq-383653104111 分钟前
(附项目源码)Java开发语言,215 springboot 大学生爱心互助代购网站,计算机毕设程序开发+文案(LW+PPT)
java·开发语言·spring boot·mysql·课程设计
ashane131414 分钟前
Java list
java·windows·list
袁庭新21 分钟前
Cannal实现MySQL主从同步环境搭建
java·数据库·mysql·计算机·java程序员·袁庭新
无尽的大道22 分钟前
深入理解 Java 阻塞队列:使用场景、原理与性能优化
java·开发语言·性能优化
建群新人小猿27 分钟前
会员等级经验问题
android·开发语言·前端·javascript·php
岁岁岁平安38 分钟前
springboot实战(15)(注解@JsonFormat(pattern=“?“)、@JsonIgnore)
java·spring boot·后端·idea
Oak Zhang39 分钟前
TheadLocal出现的内存泄漏具体泄漏的是什么?弱引用在里面有什么作用?什么情景什么问题?
java·系统安全