Supplier是Java 8引入的无参函数式接口,核心为延迟执行的工厂方法,通过get()按需创建T类型实例,支持Lambda实现,适用于延迟初始化、避免NPE、Stream生成等场景。

Supplier 是 Java 8 引入的最基础的函数式接口之一,核心作用就是“无参生产对象”——不接收任何输入,只负责在调用 get() 时返回一个指定类型的实例。
Supplier 的本质:延迟执行的工厂方法
它不是立即创建对象,而是把对象的创建逻辑封装起来,等真正需要时才执行。这种“按需供给”的特性,天然适合做延迟初始化、避免空指针、解耦对象构建过程。
- 接口定义极简:
T get(),无参数、有返回值、不抛受检异常 - 泛型 T 决定了它“生产什么”,比如
Supplier就只能返回 String 实例 - 因为是函数式接口,可直接用 Lambda 表达式实现,无需额外类或匿名内部类
常见写法:从简单到实用
你可以用一行 Lambda 完成对象供给,也可以封装复杂逻辑:
-
直接返回字面量:
Suppliers = () -> "abc"; -
调用构造器:
Supplier(等价于- > listSup = ArrayList::new;
() -> new ArrayList()) -
封装带逻辑的创建过程:
SupplieruserSup = () -> { User u = new User(); u.setId(UUID.randomUUID().toString()); return u; }; -
结合 Random 或其他状态生成器:
Supplierrand = () -> new Random().nextInt(100);
典型使用场景
Supplier 的价值不在语法本身,而在它解决的实际问题:
- 延迟初始化大对象:避免类加载时就创建耗资源实例,如数据库连接池、缓存客户端
-
避免 NPE 的安全取值:配合 Optional 使用,
Optional.ofNullable(obj).orElseGet(() -> new DefaultObj()) -
Stream 无限流生成:
Stream.generate(() -> Math.random()).limit(5) - 统一配置化对象创建:例如不同环境返回不同实现,由 Supplier 封装后注入,便于测试替换
注意几个关键细节
别被“无参”误导,它不禁止访问外部变量或状态,但要注意线程安全和副作用:
- Lambda 中可以引用 final 或事实 final 的局部变量
- 如果 Supplier 内部有状态(如共享 Random 实例),多线程并发调用
get()可能出问题,建议用ThreadLocalRandom或加锁 - 每次调用
get()都会重新执行逻辑——它不缓存结果,如需缓存需自行包装(比如配合双重检查单例或 Caffeine) - 不要在 Supplier 中做阻塞操作(如网络请求),除非你明确知道调用时机和上下文
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











