Lambda表达式可直接实现Callable接口,因其签名与call()方法一致:无参数、有返回值、可抛异常;配合ExecutorService.submit()获取Future并调用get()取结果,支持受检异常且需捕获ExecutionException。

Java 中 Callable 接口可以直接用 Lambda 表达式实现,无需额外定义类或匿名内部类,前提是 Lambda 的签名与 call() 方法一致:无参数、有返回值(可抛异常)。
Callable 的 Lambda 写法
Callable 只有一个抽象方法 call(),它不接受参数,返回泛型类型结果,且允许抛出受检异常。Lambda 表达式需匹配这个签名:
- 不能写参数列表(如
() -> ...或直接省略括号) - 必须有返回值(类型需与泛型一致)
- 可以 throw Exception,编译器会检查是否被正确处理
示例:
Callable<String> task = () -> {
Thread.sleep(100);
return "done";
};
配合 ExecutorService 使用
Lambda 形式的 Callable 常用于线程池提交异步任务并获取 Future 结果:
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
return 42;
});
System.out.println(future.get()); // 输出 42
executor.shutdown();
注意:submit() 方法重载支持 Callable,Lambda 会自动适配。
处理受检异常
call() 声明抛出 Exception,所以 Lambda 中可直接 throw 受检异常,无需包装成运行时异常:
Callable<File> fileTask = () -> {
if (!Files.exists(Paths.get("config.txt"))) {
throw new IOException("config not found");
}
return new File("config.txt");
};
调用方需在 future.get() 时捕获 ExecutionException(包装了原始异常)。
和 Runnable 的区别要点
别混淆 Runnable 和 Callable:
-
Runnable的 Lambda 是() -> { ... },无返回值、不能 throw 受检异常 -
Callable的 Lambda 必须有返回值,可 throwException,泛型决定返回类型 - 两者不能互相赋值,编译器按函数式接口签名严格匹配
例如 () -> null 是合法的 Callable<Void>,但不是 Runnable(因为 Runnable.run() 返回 void,而 void 不是类型)。

















