java中类名::new创建无参对象的前提是该类必须有可访问的无参构造器(public或包内可见),否则编译失败;如string::new合法,而localdatetime::new非法因其无无参构造器。

Java中用类名::new创建无参对象,前提是该类必须有一个**可访问的无参构造器**(默认或显式声明),否则编译不通过。
无参构造器引用的基本写法
当函数式接口的抽象方法签名与无参构造器匹配(即返回类型为该类、无参数)时,就能使用类名::new作为构造器引用。
- 常见适用接口:如
Supplier<t></t>(无参、返回T)、Callable<t></t>(无参、返回T且可能抛异常) - 示例:
Supplier<string> supplier = String::new;</string>→ 调用supplier.get()等价于new String() - 注意:
String::new能用,是因为String有公有的无参构造器;而像LocalDateTime::new会报错,因为它没有无参构造器
哪些类支持无参构造器引用?
不是所有类都能用::new生成无参实例,关键看构造器是否满足以下条件:
- 必须是
public(或对当前作用域可见,如包内访问默认构造器) - 不能是私有(
private)、受保护(protected)或缺失(如只定义了带参构造器导致默认无参被覆盖) - 例如:
ArrayList::new合法(有public ArrayList());Objects::new非法(Objects构造器是private)
实际使用场景举例
常用于集合初始化、工厂逻辑简化或配合Stream API按需创建对象:
-
List<string> list = Stream.generate(String::new).limit(3).collect(Collectors.toList());</string>→ 创建3个空字符串 -
Function<integer int> arrayCreator = int[]::new;</integer>→ 注意:这是带参构造器引用(对应new int[n]),和无参无关;无参例子应为Supplier<date> dateGen = Date::new;</date> - 自定义类需显式添加无参构造器:
class Person { public Person() {} }才能用Person::new
常见错误和排查建议
如果编译报错“cannot resolve constructor”,不要直接怀疑语法,先检查构造器本身:
- 确认类是否有无参构造器 —— 查源码或反编译,尤其注意Lombok的
@RequiredArgsConstructor会抑制默认构造器 - 检查访问权限 —— 若类在其他包,构造器必须是
public,不能是default(包级私有) - 留意静态内部类 —— 可以用
Outer.Inner::new,但非静态内部类不行(因需要外部类实例)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











