Kev*_*ker 8 java parameters return-type 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) {...}
Run Code Online (Sandbox Code Playgroud)
顾名思义,参数被忽略,甚至在实现中都没有使用.在使用中,ignoredRetVal替换为对动态代理的方法调用.由于在调用方法之前评估参数,因此在外部函数(functionFor或predicateFor等)之前调用此动态代理方法.动态代理调用记录被调用的Method(或方法链),并将其转换为Function对象(Guava)或来自多个功能库的其他类似函数的对象.
我现在要做的是创建一个类似的语义来捕获仅用于副作用的方法调用,而不需要返回类型(例如Functional Java的 Effect.如果提供了非void返回类型,则忽略它如果提供了void返回类型,它也被忽略并被接受.关键是语义必须以某种方式强制在另一个提取截获的代理方法调用的方法之前调用代理方法.并且因为我们只对side感兴趣效果,候选方法可能包括void方法.理想情况下,它看起来像:
public <T, V> Effect<T> effectFor(V ignoredRetVal) {...}
Run Code Online (Sandbox Code Playgroud)
(已经适用于非void返回类型),它可以使用如下:
Effect<MyClass> effect1 = effectFor (proxyOfMyClass.nonVoidMethod());// OK :-)
Effect<MyClass> effect2 = effectFor (proxyOfMyClass.orVoidMethod()); // Problem!!
Run Code Online (Sandbox Code Playgroud)
正如我所说,我担心我所寻找的语义不能直接支持.如果没有,那么任何替代方案都应该与我建立的模式精神上接近.此外,我的API的整个目标是减少内部类实现的"垂直噪声",我不是Double Brace Initializers的粉丝.无论提供什么建议,我都在寻找支持简洁的语义,尤其是单语句语义.
我认为您永远无法将 a 强制转换void为表达式,特别是如果您不喜欢双括号 hack。
您可以在 API 设计中遵循 Mockito 的示例。通常,您会像这样设置模拟:
when(mockedInstance.someMethod()).thenThrow(new IllegalArgumentException());
Run Code Online (Sandbox Code Playgroud)
但对于空白,你可以这样做:
doThrow(new IllegalArgumentException()).when(mockedInstance).someMethod();
Run Code Online (Sandbox Code Playgroud)
同样,您可以枚举 的方法,Effect<T>使其成为库的静态方法。
例如,如果Effect<T>有doSomething()那么你会反转它,就像
doSomething().onEffectFor(proxyInstanceOfA).methodA();
Run Code Online (Sandbox Code Playgroud)
但这假设相关方法Effect<T>本身不返回值。
如果这不是一个选项,并且您需要Effect<T>,您可以将其设置为有状态,如下所示:
VoidEffect<MyType> effect = effectForVoid(proxyOfMyClass);
effect.on().myVoidMethod();
Run Code Online (Sandbox Code Playgroud)
其中VoidEffect<T>实现Effect<Void>,并on()返回传入的代理(或不同的代理)。然后,在与 交互之前,您可能需要抛出一个IllegalStateExceptionifon()未被调用的情况effect。
| 归档时间: |
|
| 查看次数: |
2105 次 |
| 最近记录: |