0Pricing
Java Academy · 课时

构造方法引用

使用 ClassName::new,通过 Supplier 和 Function 等函数式接口创建实例

构造方法引用 是 CoddyKit 上的免费 Java Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

什么是构造器引用

构造器引用使用 ClassName::new,通过函数式接口创建对象。函数式接口的参数必须与构造器的参数匹配。

import java.util.function.*;

class Person {
    String name;
    Person(String name) { this.name = name; }
    public String toString() { return "Person(" + name + ")"; }
}

// Function<String, Person> — calls Person(String)
Function<String, Person> factory = Person::new;
Person p = factory.apply("Alice");
System.out.println(p); // Person(Alice)

将无参构造器用作 Supplier

无参构造器匹配 Supplier<T>:

class Counter {
    int count = 0;
    void inc() { count++; }
}

Supplier<Counter> newCounter = Counter::new;
Counter c1 = newCounter.get();
Counter c2 = newCounter.get(); // independent instances
c1.inc();
System.out.println(c1.count); // 1
System.out.println(c2.count); // 0

将双参数构造器用作 BiFunction

带两个参数的构造器匹配 BiFunction<T,U,R>:

record Point(int x, int y) {}

BiFunction<Integer, Integer, Point> makePoint = Point::new;
Point p = makePoint.apply(3, 4);
System.out.println(p); // Point[x=3, y=4]

Stream.map 中的构造器引用

使用构造器引用将字符串转换为对象:

import java.util.*;
import java.util.stream.*;

List<String> names = List.of("Alice","Bob","Carol");

List<Person> people = names.stream()
    .map(Person::new)  // calls new Person(name) for each
    .collect(Collectors.toList());

people.forEach(System.out::println);
// Person(Alice)
// Person(Bob)
// Person(Carol)

数组构造器引用

使用 Type[]::new 动态创建数组。Stream.toArray() 会使用这种方式:

import java.util.stream.*;

String[] arr = Stream.of("a","b","c")
    .toArray(String[]::new);

for (String s : arr) System.out.print(s + " ");
// a b c

int[] sizes = {3, 5, 2};
String[][] matrix = Arrays.stream(sizes)
    .mapToObj(String[]::new)
    .toArray(String[][]::new);

Factory 接口模式

为工厂定义自定义函数式接口,然后使用构造器引用:

@FunctionalInterface
interface Factory<T> {
    T create(String config);
}

class DBConnection {
    String url;
    DBConnection(String url) { this.url = url; }
    public String toString() { return "DB(" + url + ")"; }
}

Factory<DBConnection> dbFactory = DBConnection::new;
DBConnection conn = dbFactory.create("jdbc:postgresql://localhost/mydb");
System.out.println(conn);

使用构造器引用进行依赖注入

框架通常使用函数式工厂来延迟实例化。构造器引用可以让这种模式更加简洁:

import java.util.function.*;

class ServiceLocator {
    private final Map<String, Supplier<?>> registry = new HashMap<>();
    
    <T> void register(String name, Supplier<T> factory) {
        registry.put(name, factory);
    }
    
    @SuppressWarnings("unchecked")
    <T> T get(String name) { return (T) registry.get(name).get(); }
}

ServiceLocator loc = new ServiceLocator();
loc.register("counter", Counter::new);
Counter c = loc.get("counter");

在 Lambda 与构造器引用之间进行选择

当 lambda 体只是 new Type(args) 时,请使用构造器引用:

// Lambda:
Function<String, Person> f1 = name -> new Person(name);

// Constructor reference (preferred):
Function<String, Person> f2 = Person::new;

// When you need extra logic, stick with lambda:
Function<String, Person> f3 = name -> new Person(name.trim().toLowerCase());

泛型类型与构造器引用

泛型类同样适用——类型会根据函数式接口的上下文推断出来:

import java.util.*;
import java.util.function.*;

// ArrayList::new matches Supplier<ArrayList<String>>
Supplier<List<String>> listFactory = ArrayList::new;
List<String> l1 = listFactory.get();
List<String> l2 = listFactory.get(); // independent lists
l1.add("hello");
System.out.println(l2.size()); // 0

使用构造器引用的流集合器

在集合器中使用构造器引用来构建自定义结果容器:

import java.util.stream.*;

// Collect into a LinkedList using a constructor reference supplier
LinkedList<String> linked = Stream.of("a","b","c")
    .collect(Collectors.toCollection(LinkedList::new));
System.out.println(linked.getFirst()); // a

基本类型与自动装箱

包装类型的构造器引用会处理自动装箱:

// Integer::new is deprecated in Java 9+, but illustrates the concept
// Use Integer.valueOf or just autoboxing in modern Java
Function<String, Integer> intParser = Integer::parseInt; // static method ref
System.out.println(intParser.apply("42")); // 42

快速检查

像 ArrayList::new 这样的无参构造器引用匹配哪种函数式接口?

回顾:构造器引用

要点:

  • 语法:ClassName::new——委托给匹配的构造器
  • 无参 → Supplier<T>;单参数 → 函数接口<T,R>;双参数 → BiFunction
  • 数组构造器:Type[]::new——与 Stream.toArray() 一起使用
  • 当 lambda 体只是“new Type(args)”时,它比 lambda 更简洁
  • 使用 Collectors.toCollection(LinkedList::new) 获取具有指定类型的集合结果

常见问题解答

「构造方法引用」课时是免费的吗?

是的 — 「构造方法引用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「构造方法引用」这节课中我会学到什么?

使用 ClassName::new,通过 Supplier 和 Function 等函数式接口创建实例 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「构造方法引用」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 静态方法引用
  2. 特定实例上的实例方法引用
  3. 任意实例的方法引用
  4. 构造方法引用
← 返回 Java Academy