Supplier接口是Java 8引入的函数式接口,位于java.util.function包下,它的核心作用是提供一个数据结果,且不需要接收任何输入参数,非常适合用来封装数据获取的逻辑,实现数据提供的延迟性和灵活性。

Supplier接口的基本定义
Supplier接口只有一个抽象方法get(),该方法没有参数,返回一个泛型指定的结果类型。因为它是函数式接口,所以可以通过lambda表达式或者方法引用来创建实例。接口的简化定义如下:
@FunctionalInterface
public interface Supplier<T> {
T get();
}Supplier接口的基础使用
最基本的用法是直接通过lambda表达式实现get方法,返回对应的数据。比如我们需要提供一个字符串数据,可以这样写:
import java.util.function.Supplier;
public class SupplierDemo {
public static void main(String[] args) {
// 使用lambda表达式创建Supplier实例,提供字符串数据
Supplier<String> stringSupplier = () -> "Hello Supplier";
// 调用get方法获取数据
String result = stringSupplier.get();
System.out.println(result); // 输出 Hello Supplier
}
}也可以使用方法引用来创建Supplier实例,当数据已经存在于某个方法的返回结果中时,这种方式更简洁:
import java.util.function.Supplier;
public class SupplierMethodRef {
public static String getDefaultName() {
return "默认用户";
}
public static void main(String[] args) {
// 方法引用创建Supplier实例
Supplier<String> nameSupplier = SupplierMethodRef::getDefaultName;
System.out.println(nameSupplier.get()); // 输出 默认用户
}
}Supplier接口的典型应用场景
延迟加载数据
当数据的获取成本比较高,且不一定每次都会用到时,可以用Supplier实现延迟加载,只有真正需要数据的时候才执行获取逻辑:
import java.util.function.Supplier;
public class LazyLoadDemo {
// 模拟高成本的数据获取方法
private static String queryFromDb() {
System.out.println("执行数据库查询操作");
try {
Thread.sleep(1000); // 模拟查询耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
return "查询结果数据";
}
public static void main(String[] args) {
// 封装数据获取逻辑到Supplier,此时不会执行queryFromDb
Supplier<String> dataSupplier = () -> queryFromDb();
// 模拟业务逻辑判断,不需要数据时不会触发查询
boolean needData = false;
if (needData) {
String data = dataSupplier.get(); // 只有这里才会执行queryFromDb
System.out.println("使用数据:" + data);
} else {
System.out.println("不需要使用数据,未触发查询");
}
}
}配合Optional处理空值
Optional类的orElseGet方法接收Supplier作为参数,当Optional为空时,才会调用Supplier的get方法获取数据,比直接使用orElse更高效:
import java.util.Optional;
import java.util.function.Supplier;
public class OptionalSupplierDemo {
public static void main(String[] args) {
Optional<String> optional = Optional.empty();
// 只有optional为空时,才会执行Supplier的get方法
Supplier<String> defaultSupplier = () -> {
System.out.println("执行默认数据生成逻辑");
return "默认数据";
};
String result = optional.orElseGet(defaultSupplier);
System.out.println(result); // 输出 默认数据
}
}实现简单工厂模式
可以用Supplier来封装对象的创建逻辑,根据不同的条件返回不同的Supplier实例,实现简单工厂的效果:
import java.util.function.Supplier;
class Product {
private String name;
public Product(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Phone extends Product {
public Phone() {
super("手机");
}
}
class Computer extends Product {
public Computer() {
super("电脑");
}
}
public class FactoryDemo {
// 根据类型返回对应的对象创建Supplier
public static Supplier<Product> getProductSupplier(String type) {
if ("phone".equals(type)) {
return Phone::new;
} else if ("computer".equals(type)) {
return Computer::new;
}
return null;
}
public static void main(String[] args) {
Supplier<Product> phoneSupplier = getProductSupplier("phone");
Product phone = phoneSupplier.get();
System.out.println(phone.getName()); // 输出 手机
Supplier<Product> computerSupplier = getProductSupplier("computer");
Product computer = computerSupplier.get();
System.out.println(computer.getName()); // 输出 电脑
}
}使用注意事项
- Supplier的get方法每次调用都会执行一遍封装的逻辑,如果需要多次使用同一个结果,建议将结果缓存,避免重复执行高成本的逻辑。
- Supplier本身不要求线程安全,如果需要在多线程场景下使用,需要额外添加同步逻辑。
- 不要将Supplier的get方法和有副作用的逻辑绑定,比如修改外部变量,尽量让Supplier只做数据返回的操作,符合函数式接口的纯函数特性。
JavaSupplier接口函数式接口数据提供lambda表达式修改时间:2026-06-03 15:32:24