繁体   English   中英

接受void的通用参数类型

[英]Generic parameter type that accepts void

我正在尝试为我正在从事的开源项目创建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替换为对动态代理的方法调用。 由于参数是在调用方法之前评估的,因此此动态代理方法在外部函数( functionForpredicateFor等)之前被调用。 动态代理调用记录了调用的Method (或方法链),并将其转换为Function对象(Guava)或来自多个功能库的其他类似函数的对象。

我现在想要做的是创建一个类似的语义,该语义仅捕获用于副作用的方法调用,而无需任何返回类型(例如, Functional Java的 Effect 。如果提供了非无效的返回类型,则为如果提供了void返回类型,则它也将被忽略并被接受,关键是语义必须以某种方式强制调用代理方法,然后再调用另一个方法来提取被拦截的代理方法调用。副作用,候选方法可能包括void方法。理想情况下,它看起来像:

public <T, V> Effect<T> effectFor(V ignoredRetVal) {...}

(已经适用于非无效返回类型),可以按以下方式使用它:

Effect<MyClass> effect1 = effectFor (proxyOfMyClass.nonVoidMethod());// OK :-)
Effect<MyClass> effect2 = effectFor (proxyOfMyClass.orVoidMethod()); // Problem!!

正如我所说,恐怕我要寻找的语义不能直接支持。 如果没有,那么任何选择都应在精神上与我所确立的模式接近。 而且,我API的全部目标是减少内部类实现的“垂直噪声”,而且我也不喜欢Double Brace Initializers。 无论提供什么建议,我都在寻找一种支持简洁的语义,尤其是单语句语义。

我认为您永远无法将void强制为表达式,特别是如果您不喜欢双重括号黑客。

您可以在API设计中遵循Mockito的示例。 通常,您可以这样设置一个模拟:

when(mockedInstance.someMethod()).thenThrow(new IllegalArgumentException());

但是要作废,您可以这样做:

doThrow(new IllegalArgumentException()).when(mockedInstance).someMethod();

同样,您可以枚举Effect<T>的方法以使其成为库的静态方法。

例如,如果Effect<T>具有doSomething() ,则将其反转,例如

doSomething().onEffectFor(proxyInstanceOfA).methodA();

但这假设Effect<T>的相关方法本身未返回值。

如果这不是一个选择,并且您需要Effect<T> ,则可以使其有状态,如下所示:

VoidEffect<MyType> effect = effectForVoid(proxyOfMyClass);
effect.on().myVoidMethod();

其中VoidEffect<T>实现Effect<Void>on()返回传入的代理(或其他代理)。 然后,如果on()未与effect交互之前未调用on()则可能要抛出IllegalStateException

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM