构造器引用(如String::new)不是new的简写,不直接创建实例,仅是匹配函数式接口的语法糖;真正实例化发生在调用处(如map、get等),需参数和返回类型与目标接口抽象方法一致。

Java 中的构造器引用(Constructor Reference)本身 不会 通过 new 关键字直接创建对象实例,它只是对构造器的一种简洁写法,用于替代 Lambda 表达式,在函数式接口需要“创建对象”逻辑时使用。真正调用 new 创建实例的是在运行时被调用该构造器引用的地方(比如 map()、supply() 等方法内部),而不是在声明构造器引用时。
构造器引用的本质是语法糖
构造器引用(如 String::new、ArrayList::new)本质上是将某个类的构造器“当作一个方法”来对待,要求其签名必须匹配目标函数式接口的抽象方法。它不执行任何实例化动作,只是一种类型兼容的引用。
例如:
✔ 正确:构造器引用作为参数传入,由接收方决定何时调用List<String> strings = Arrays.asList("a", "b", "c");
// String::new 匹配 Function<String, String> 的 apply(String) → String
List<String> copies = strings.stream().map(String::new).collect(Collectors.toList());
// 这里每个 String("a")、String("b") 才真正触发 new String(String)
哪些函数式接口常配合构造器引用使用
只有当函数式接口的抽象方法返回值是目标类型、且参数列表与构造器参数一致时,才能使用对应构造器引用:
立即学习“Java免费学习笔记(深入)”;
-
Supplier<T>→ 无参构造器:ArrayList::new、HashMap::new -
Function<T, R>或UnaryOperator<T>→ 单参数构造器:String::new(String(char[])、String(String)等) -
BiFunction<T, U, R>→ 双参数构造器:BigDecimal::new(BigDecimal(String, MathContext)) -
Function<int[], int[]>→ 数组构造器:int[]::new(等价于size -> new int[size])
构造器引用不是 new 的简写,不能独立执行
下面写法是错误或无意义的:
✘ 错误:构造器引用不能单独放在语句中,也不会触发 newString::new; // 编译错误:不是语句,也不能赋值给任意类型 new String::new(); // 语法错误:new 后面必须是类名,不是引用
正确用法必须绑定到兼容的函数式接口变量或方法参数中:
Supplier<List<String>> listFactory = ArrayList::new; List<String> list = listFactory.get(); // ← 此时才执行 new ArrayList<>()
自定义类的构造器引用示例
假设有一个类:
class Person {
private final String name;
private final int age;
Person(String name) { this(name, 0); }
Person(String name, int age) { this.name = name; this.age = age; }
}
可这样使用构造器引用:
-
Person::new可用于BiFunction<String, Integer, Person>(匹配两参数构造器) -
Person::new也可用于Function<String, Person>(匹配单参数构造器) - 但不能用于
Supplier<Person>,因为没有无参构造器(除非显式添加)


















