Java: 构造器表达式 Constructor Expression /构造器引用(Constructor Reference)

目录

    • 概念:
    • 适用场景
      • [1. 无参构造器引用](#1. 无参构造器引用)
      • [2. 有参构造器引用](#2. 有参构造器引用)
      • [3. 数组构造器引用](#3. 数组构造器引用)
    • 核心要点

概念:

在 Java 中,"constructor expression"(构造器表达式)通常指的是使用构造器引用(Constructor Reference)的表达式,这是 Java 8 引入的 Lambda 表达式的一种简化形式,用于引用类的构造器。

构造器引用允许你通过类名和 new 关键字来引用构造器,而不必显式写出 Lambda 表达式的参数和new调用。它的语法形式是:
类名::new

适用场景

当 Lambda 表达式的参数列表与某个类的构造器参数列表完全一致,且 Lambda 表达式的功能就是通过这些参数创建该类的实例时,就可以用 构造器引用 简化代码。

示例说明

1. 无参构造器引用

如果类有一个无参构造器,且函数式接口的抽象方法无参数并返回该类的实例:

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

class Person {
    public Person() { // 无参构造器
        System.out.println("创建Person实例");
    }
}

public class Main {
    public static void main(String[] args) {
        // 使用Lambda表达式
        Supplier<Person> supplier1 = () -> new Person();
        Person p1 = supplier1.get();
        
        // 使用构造器引用(简化形式)
        Supplier<Person> supplier2 = Person::new; // 引用无参构造器
        Person p2 = supplier2.get();
    }
}

2. 有参构造器引用

如果类有一个带参数的构造器,且函数式接口的抽象方法参数与构造器参数匹配:

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

class Person {
    private String name;
    
    public Person(String name) { // 带参构造器
        this.name = name;
        System.out.println("创建Person实例:" + name);
    }
}

public class Main {
    public static void main(String[] args) {
        // 使用Lambda表达式
        Function<String, Person> function1 = (name) -> new Person(name);
        Person p1 = function1.apply("Alice");
        
        // 使用构造器引用(简化形式)
        Function<String, Person> function2 = Person::new; // 引用带参构造器
        Person p2 = function2.apply("Bob");
    }
}

3. 数组构造器引用

构造器引用也可以用于数组(数组的构造器本质是new 类型[长度]):

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

public class Main {
    public static void main(String[] args) {
        // 使用Lambda表达式创建int数组
        IntFunction<int[]> arrayCreator1 = (length) -> new int[length];
        int[] arr1 = arrayCreator1.apply(5); // 创建长度为5的int数组
        
        // 使用构造器引用创建int数组
        IntFunction<int[]> arrayCreator2 = int[]::new; // 引用数组构造器
        int[] arr2 = arrayCreator2.apply(10); // 创建长度为10的int数组
    }
}

核心要点

  • 构造器引用是 Lambda 表达式的语法糖,本质上是对构造器的间接调用。
  • 引用的构造器参数列表必须与函数式接口中抽象方法的参数列表完全匹配(数量、类型、顺序一致)。
  • 通过 类名::new 的形式,代码更简洁、可读性更高,尤其在集合操作(如Stream.map())中常用。
    例如,在 Stream 中批量创建对象:
java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Person {
    private String name;
    public Person(String name) { this.name = name; }
}

public class Main {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        
        // 将字符串列表转换为Person对象列表
        List<Person> people = names.stream()
                .map(Person::new) // 等价于 (name) -> new Person(name)
                .collect(Collectors.toList());
    }
}