构造器引用是方法引用的一种,语法为ClassName::new,用于Lambda中简洁创建对象,JVM根据函数式接口自动匹配对应构造器。

Java 中构造器引用是方法引用的一种,用于在 Lambda 表达式中简洁地代替创建对象的逻辑,本质是将“调用某个类的构造器”这一操作作为函数式接口的实现。
构造器引用的基本语法
格式为:ClassName::new。JVM 会根据上下文函数式接口的抽象方法签名,自动匹配对应参数数量和类型的构造器。
- 无参构造器:String::new → 对应 Supplier<String>
- 单参构造器:File::new → 对应 Function<String, File>(接收路径字符串,返回 File 实例)
- 双参构造器:HashMap::new → 对应 BiFunction<Integer, Float, HashMap>(需注意:实际常用的是 Supplier 或 Function,双参通常需自定义函数接口或配合重载)
常见使用场景与示例
构造器引用最常用于工厂类、集合转换、Stream 操作等需要批量创建对象的地方。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用 Supplier 创建新实例:
List<String> list = Arrays.asList("a", "b");
List<StringBuilder> builders = list.stream()
.map(StringBuilder::new)
.collect(Collectors.toList()); - 用 Function 将输入映射为对象:
Function<String, Integer> strToInt = Integer::new;
int num = strToInt.apply("123"); // 等价于 new Integer("123") - 配合自定义函数接口支持多参构造:
interface TriFunction<A,B,C,R> { R apply(A a, B b, C c); }
TriFunction<String,String,Integer,Person> personCtor = Person::new;
Person p = personCtor.apply("张", "三", 25);
注意事项与限制
构造器引用不是万能的,需注意类型推断是否准确、构造器是否可访问、以及是否存在歧义。
立即学习“Java免费学习笔记(深入)”;
- 若类有多个构造器且参数类型相近(如 int 和 long),编译器可能无法推断,需显式声明函数式接口类型或改用 Lambda
- 私有构造器不可被引用(除非在同一个类内,且接口在作用域内)
- 泛型类的构造器引用需注意类型擦除,如 ArrayList::new 实际推断为 Supplier<ArrayList<Object>>,不能直接用于 Supplier<ArrayList<String>>
与普通 Lambda 的对比优势
构造器引用更简洁、语义更清晰,且性能略优(避免了 Lambda 实例的额外开销)。
- 等价写法对比:
// Lambda 写法
Function<String, BigDecimal> f1 = s -> new BigDecimal(s);
// 构造器引用写法
Function<String, BigDecimal> f2 = BigDecimal::new; - 当构造逻辑简单且仅涉及 new 调用时,优先用构造器引用;若需预处理、条件判断或调用静态工厂方法,则仍需 Lambda

















