supplier 是 java 8 的函数式接口,用于无参延迟供给对象,仅含抽象方法 t get(),支持 lambda、方法引用和匿名类实现,相比 new 能避免提前初始化、规避异常及实现多次独立创建。

Supplier 是 Java 8 引入的函数式接口,用于延迟生成(供给)一个结果,不接收参数、返回一个值。它天然适合实现无参构造的数据延迟供给——即“用时才创建”,避免提前初始化开销或副作用。
理解 Supplier 的核心契约
Supplier
T get()
这个方法无入参、有返回值,调用时机完全由你控制。只要把对象创建逻辑写在 get() 里,就实现了真正的延迟供给。
常见实现方式
-
Lambda 表达式(最常用)
Supplier<list>> listSupplier = () -> new ArrayList();</list>
每次调用listSupplier.get()都新建一个空列表,互不影响。 -
方法引用(适合复用已有工厂方法)
Supplier<localdatetime> nowSupplier = LocalDateTime::now;</localdatetime>
每次调用都获取当前时间戳,不是“创建时”的快照。 -
匿名内部类(适合复杂初始化逻辑)
Supplier<connection> connSupplier = new Supplier() {<br> public Connection get() {<br> return DriverManager.getConnection(url, user, pwd);<br> }<br>};</connection>
连接只在真正需要时建立,避免连接泄漏或过早失败。
与普通构造的区别在哪
普通 new 创建是立即执行;Supplier 将创建动作封装成可执行单元,推迟到 get() 被显式调用时才发生。这带来几个关键好处:
- 避免不必要的对象创建(如配置未加载完成时先占内存)
- 规避可能抛异常的初始化(如文件不存在、网络不通),让错误发生在真正使用时
- 支持按需、多次、独立地生成新实例(每个
get()都是干净的新对象)
典型使用场景
-
测试中提供干净的测试数据:
Supplier<user> userSupplier = () -> User.builder().name("test").build();</user>
每个测试用例调用一次,确保状态隔离。 -
配置类懒加载字段:
private final Supplier<mapper> mapperSupplier = () -> new MyBatisMapper(...);</mapper>
类初始化时不触发 Mapper 构造,首次调用mapperSupplier.get()才初始化。 -
日志或调试中的惰性字符串拼接:
log.debug("User info: {}", () -> user.toJsonString());
日志级别关闭时,toJsonString()根本不会执行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











