我正在尝试为我正在从事的开源项目创建 API,并且在尝试扩展 API 同时保持语义与当前 API 一致时遇到了障碍。我希望能够定义一个带有通用参数的方法签名,该参数接受调用任何方法签名的结果。“任何”意味着包括void
方法。我已经知道你不能直接定义参数类型void
——请不要重复这个明显的事实。不明显的是是否有任何技巧void
可以将方法调用作为参数提供给方法(即,并忽略)。
背景故事,所以这更有意义我为什么想做这样的事情,以及我的设计目标和约束是什么,以防上述是不可能的(我担心它是):
我当前的 API 定义了一种非常可重复的方法模式,如下所示:
public <T,V> Function<T,V> functionFor(V ignoredRetVal) {...}
public <T> Predicate<T> predicateFor(V ignoredRetVal) {...}
public <T> Filter<T> filterFor(V ignoredRetVal) {...}
顾名思义,参数被忽略,甚至没有在实现中使用。在使用中,ignoredRetVal
被替换为对动态代理的方法调用。functionFor
由于在调用方法之前评估参数,因此在外部函数(或predicateFor
等)之前调用此动态代理方法。动态代理调用记录调用的Method
(或方法链),并将其Function
从多个函数库中转换为对象(Guava)或其他类似函数的对象。
我现在要做的是创建一个类似的语义,该语义捕获仅用于副作用的方法调用,而不需要返回类型(例如函数式 Java 的 Effect
. 如果提供了非 void 返回类型,则将其忽略. 如果提供了 void 返回类型,它也会被忽略和接受。关键是语义必须以某种方式强制代理方法在另一个提取截获的代理方法调用的方法之前被调用。因为我们只对 side 感兴趣效果,候选方法很可能包括void
方法。理想情况下,它看起来像:
public <T, V> Effect<T> effectFor(V ignoredRetVal) {...}
(它已经适用于非 void 返回类型),它可以按如下方式使用:
Effect<MyClass> effect1 = effectFor (proxyOfMyClass.nonVoidMethod());// OK :-)
Effect<MyClass> effect2 = effectFor (proxyOfMyClass.orVoidMethod()); // Problem!!
正如我所说,恐怕我正在寻找的语义不能直接支持。如果不是,那么任何替代方案都应该在精神上接近我建立的模式。此外,我的 API 的整个目标是减少内部类实现的“垂直噪音”,我不是双括号初始化器的粉丝。无论提供什么建议,我都在寻找一种支持简洁的语义,尤其是单语句语义。