Java中构造器引用ClassName::new本质是将构造器作为函数式接口实现,其参数个数和类型由接收它的函数式接口抽象方法签名决定:无参对应Supplier<T>,单参对应Function<A,T>,双参对应BiFunction<A,B,T>,三参及以上需自定义函数式接口或改用Lambda。

Java中用类名::new创建带参对象,本质是把构造器当作函数式接口的实现来使用,参数个数和类型必须与目标函数式接口的抽象方法签名严格匹配。
构造器引用如何对应不同参数数量
构造器引用ClassName::new本身不显式写参数,它“适配”的参数由接收它的函数式接口决定。编译器根据上下文自动绑定参数到构造器:
-
无参构造器 → 对应
Supplier<T>(get()无参,返回对象) -
单参构造器 → 对应
Function<A, T>(apply(A)接收1个参数,返回对象) -
双参构造器 → 对应
BiFunction<A, B, T>(apply(A, B)接收2个参数,返回对象) - 三参及以上构造器 → 需自定义函数式接口,或改用Lambda表达式
常见用法示例
假设有类:
class Person {<br> Person() { /* 无参 */ }<br> Person(String name) { /* 单参 */ }<br> Person(String name, int age) { /* 双参 */ }<br>}
对应使用方式:
立即学习“Java免费学习笔记(深入)”;
-
Supplier<Person> s = Person::new;→ 调用s.get()创建无参对象 -
Function<String, Person> f = Person::new;→ 调用f.apply("Alice")创建单参对象 -
BiFunction<String, Integer, Person> bf = Person::new;→ 调用bf.apply("Bob", 25)创建双参对象
注意点和限制
构造器引用不是万能语法糖,有明确约束:
- 必须存在**可访问的、参数匹配的构造器**,否则编译报错
- 不能直接指定参数值(如
Person::new("Tom")是非法的) - 若类只有私有构造器,且无对应访问权限,引用会失败
- 泛型类需注意类型推断,必要时显式指定,如
ArrayList<String>::new
无法直接支持的场景怎么办
比如想用三参数构造器,但标准函数式接口只到 BiFunction:
- 定义自己的函数式接口,例如:
@FunctionalInterface<br>interface TriFunction<A,B,C,R> { R apply(A a, B b, C c); } - 然后写:
TriFunction<String,Integer,Boolean,Person> tf = Person::new;(前提是存在三参构造器) - 或者更简单:直接用 Lambda,如
(n,a,act) -> new Person(n,a,act)
不复杂但容易忽略:构造器引用的核心是“接口驱动”,不是“构造器驱动”。写 Person::new 本身没意义,只有把它赋给某个函数式接口变量或传给期望该接口的方法时,才真正生效并绑定参数。


















