如何链式调用方法引用?能否构建方法引用链实现通用空值校验?
方法引用链式调用的实现方案
嘿,这个想法挺有意思的!不过遗憾的是,Java原生并不支持你写的Product::getType::getTypeInfo::getTypeInfoId这种直接链式的方法引用语法——方法引用本身是单个方法的引用,没办法直接通过::运算符连起来形成调用链条。不过别担心,我们可以用Java 8引入的Function接口的andThen()方法来实现类似的效果,完全能满足你做通用空值校验的需求。
一、构建方法引用链
我们可以把每个方法引用转换成对应的Function实例,然后用andThen()方法把它们依次串联起来,形成一个完整的调用链。举个具体的例子:
// 先定义单个方法对应的Function Function<Product, Type> getTypeFunc = Product::getType; Function<Type, TypeInfo> getTypeInfoFunc = Type::getTypeInfo; Function<TypeInfo, String> getTypeInfoIdFunc = TypeInfo::getTypeInfoId; // 用andThen()组合成链式调用 Function<Product, String> chain = getTypeFunc.andThen(getTypeInfoFunc).andThen(getTypeInfoIdFunc);
如果你想更简洁一点,也可以直接链式编写,不过第一个方法引用需要显式指定类型(帮助Java编译器做类型推断):
Function<Product, String> chain = ((Function<Product, Type>) Product::getType) .andThen(Type::getTypeInfo) .andThen(TypeInfo::getTypeInfoId);
二、实现通用空值校验方法
你原有的方法声明和实现有一点小问题(返回值类型不匹配),我们可以调整成下面这样,利用Optional的map()方法自动处理空值:
import java.util.Optional; import java.util.function.Function; public class NullCheckUtil { public <T, R> Optional<R> checkIfNull(T object, Function<T, R> chain) { // 如果object为空,或者链条中任何一步返回null,最终都会得到空的Optional return Optional.ofNullable(object).map(chain); } }
调用这个方法的时候,只要传入目标对象和我们构建好的方法引用链,就能轻松完成空值校验:
public class Demo { public static void main(String[] args) { NullCheckUtil util = new NullCheckUtil(); Product product = new Product(); // 假设这是你的产品实例 Function<Product, String> chain = ((Function<Product, Type>) Product::getType) .andThen(Type::getTypeInfo) .andThen(TypeInfo::getTypeInfoId); Optional<String> result = util.checkIfNull(product, chain); // 处理结果 result.ifPresent(id -> System.out.println("获取到类型ID:" + id)); if (result.isEmpty()) { System.out.println("对象或链条中某个环节为空"); } } }
三、封装工具类简化链式构建
如果经常需要构建这种方法引用链,我们可以封装一个工具类,让代码更简洁:
import java.util.function.Function; public class FunctionChain { @SafeVarargs public static <T> Function<T, Object> chain(Function<?, ?>... functions) { if (functions == null || functions.length == 0) { throw new IllegalArgumentException("至少需要传入一个Function"); } @SuppressWarnings("unchecked") Function<T, Object> result = (Function<T, Object>) functions[0]; for (int i = 1; i < functions.length; i++) { result = result.andThen((Function<Object, Object>) functions[i]); } return result; } }
使用这个工具类的时候,代码会更清爽:
Function<Product, Object> chain = FunctionChain.chain( Product::getType, Type::getTypeInfo, TypeInfo::getTypeInfoId );
补充说明
如果你真的想让语法更接近你最初设想的Product::getType::getTypeInfo这种形式,可能需要借助第三方函数式库,但如果只用原生Java,上面的方案就是最标准、最易维护的实现方式了。
内容的提问来源于stack exchange,提问作者hellzone
相关产品推荐
相关产品推荐

