类名::new用于引用类的构造器,需函数式接口抽象方法签名与构造方法参数完全匹配:无参→supplier、单参→function、双参→bifunction、数组→intfunction。

Java 中用 类名::new 是方法引用的一种形式,专门用于引用类的构造器,本质是把“创建对象”这个动作作为函数式接口的实现,常用于配合 Supplier、Function、BiFunction 等接口完成简洁的对象实例化。
什么时候能用 类名::new?
前提是目标类有对应参数结构的构造方法,且函数式接口的抽象方法签名与该构造方法**参数类型和数量完全匹配**。编译器会自动绑定。
- 无参构造 → 匹配
Supplier<t></t>(get()无参,返回 T) - 单个参数构造 → 匹配
Function<a t></a>(apply(A)接收 A,返回 T) - 两个参数构造 → 匹配
BiFunction<a b t></a>(apply(A, B)接收 A 和 B,返回 T) - 数组构造(如
String[]::new)→ 匹配IntFunction<t></t>(apply(int)接收长度,返回 T[])
常见写法示例
假设有一个简单类:
class Person {
String name;
int age;
Person() {}
Person(String name) { this.name = name; }
Person(String name, int age) { this.name = name; this.age = age; }
}
- 调用无参构造:
Supplier<person> s = Person::new; Person p1 = s.get();</person> - 调用单参构造:
Function<string person> f = Person::new; Person p2 = f.apply("Alice");</string> - 调用双参构造:
BiFunction<string integer person> bf = Person::new; Person p3 = bf.apply("Bob", 25);</string> - 创建字符串数组:
IntFunction<string> arrayCreator = String[]::new; String[] arr = arrayCreator.apply(3); // new String[3]</string>
注意点和限制
类名::new 不是万能语法糖,它依赖函数式接口的上下文推断。如果构造器被重载,编译器必须能唯一确定使用哪一个;否则会报错。
- 不能直接传入具体值(如
Person::new("Tom")❌),必须通过函数式接口的抽象方法传参 - 私有构造器也可引用,只要当前作用域有访问权限
- 泛型类需注意类型擦除,如
ArrayList::new实际匹配的是原始类型构造器,通常推荐显式写成ArrayList<string>::new</string>(但编译器常可推断) - 若构造器抛出受检异常,而目标函数式接口不声明该异常,则无法直接引用(需包装或改用 Lambda)
对比 Lambda 更简洁在哪?
等价写法对比:
-
Supplier<person> s = () -> new Person();</person>⇄Supplier<person> s = Person::new;</person> -
Function<string person> f = name -> new Person(name);</string>⇄Function<string person> f = Person::new;</string>
后者更简短、语义更清晰——明确表达“按此签名调用构造器”,且避免了冗余的参数声明和括号,尤其在链式调用或 Stream 操作中(如 stream.map(Person::new))更易读。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











