太长别读:我试图找到最有效的动态创建功能接口的实现,将调用转发到该接口的一组实例。
目标是简化接口的实现,通过将处理程序(实现为功能接口)传递给适当的注册函数,允许客户端代码为多个事件注册自己。例如:
/** The interface in question we want to implement with minimal effort. */
interface TrainStation {
void onTranArrived(TrainArrivedHandler handler);
void onPassengerArrived(PassengerArrivedHandler handler);
interface TrainArrivedHandler {
void apply(String track, String lineNumber);
}
interface PassengerArrivedHandler {
void apply(String track);
}
}
这可能是这种接口的一个示例。有许多这样的接口,每个接口都有不同的事件,因此实现应该尽可能简单,没有太多重复的代码。我想这最好是通过在这样的实现中引入一个内部使用的Event
类型来实现,它允许将调用转发到所有注册的处理程序:
/** Used in an implementation to implement on*() functions. */
interface Event<HANDLER> {
/** Register a handler. */
void on(HANDLER handler);
/** Returned instance calls all registered handlers. */
HANDLER getMasterHandler();
static <HANDLER> Event<HANDLER> create() {
// Magic. May need an instance of Class<HANDLER>, which is okay.
}
}
然后,TrainStation
的实现可能如下所示:
final class TrainStationImpl implements TrainStation {
private final Event<TrainArrivedHandler> trainArrivedEvent = Event.create();
private final Event<PassengerArrivedHandler> passengerArrivedEvent = Event.create();
@Override
public void onTranArrived(TrainArrivedHandler handler) {
trainArrivedEvent.on(handler);
}
@Override
public void onPassengerArrived(PassengerArrivedHandler handler) {
passengerArrivedEvent.on(handler);
}
/** Generates some events. */
public void makeSomethingHappen() {
trainArrivedEvent.getMasterHandler().apply("34", "S12");
passengerArrivedEvent.getMasterHandler().apply("2"); // Wants to catch the S12, but is obviously too late now.
}
}
这是一个可管理的所需代码级别。它的大部分可以提取到一个抽象类中,因此每个接口只需要一次。当然,任何减少它的方法都是一个优点,但我看不到不公开事件
实例的简单方法。
随着这种方法的发展,有趣的事情是接口事件
的实现。我当然可以想象用普通的旧反射来做这件事,这是可以接受的,但不是真正出色的性能。但是我认为Java1.7或1.8现在应该有一种更有效和/或更直接的方法来实现Event.getMasterHandler()
的返回值,使用新的API,尤其是方法处理
,因为我们知道每个处理程序接口都是一个功能接口。我该如何做到这一点?
虽然原则上,您可以使用方法句柄
来构造委托给多个目标的组合句柄,但没有办法以功能接口
的有效实现的形式提供它。
LambdaMetafactory
创建高效的实现,但目前仅支持直接方法句柄,因此您不能在此处使用组合句柄。MethodHandleProxies
支持任意句柄,但当前使用反射代理
功能,您希望避免其开销。
最好的解决方案是接受每个接口
需要一些显式代码,但使用 Java
interface TrainArrivedHandler {
void apply(String track, String lineNumber);
static TrainArrivedHandler forAll(Iterable<TrainArrivedHandler> all) {
return (track, lineNumber) -> all.forEach(h -> h.apply(track, lineNumber));
}
}
interface PassengerArrivedHandler {
void apply(String track);
static PassengerArrivedHandler forAll(Iterable<PassengerArrivedHandler> next) {
return track -> next.forEach(h -> h.apply(track));
}
}
final class TrainStationImpl implements TrainStation {
private final Set<TrainArrivedHandler> trainArrivedHandler=new HashSet<>();
private final Set<PassengerArrivedHandler> passengerArrivedHandler=new HashSet<>();
public void onTranArrived(TrainArrivedHandler handler) {
trainArrivedHandler.add(handler);
}
public void onPassengerArrived(PassengerArrivedHandler handler) {
passengerArrivedHandler.add(handler);
}
/** Generates some events. */
public void makeSomethingHappen() {
TrainArrivedHandler.forAll(trainArrivedHandler).apply("34", "S12");
// Wants to catch the S12, but is obviously too late now.
PassengerArrivedHandler.forAll(passengerArrivedHandler).apply("2");
}
}
请注意,保存侦听器的< code >集合的实际类型没有硬连线到< code >接口中,事实上,任何< code>Iterable都可以。因此,我在这里使用< code>Set作为示例,但是如果您愿意,您可以创建一个更复杂的专用于侦听器存储的解决方案。它可以完全按照您的问题的意图通用,它只需实现< code>Iterable,而使用正确参数类型调用每个侦听器将由侦听器< code >接口处理
使用ByteBuddy,我可以通过调用另一个实例方法并转换结果来实现一个实例方法吗? 例如(玩具): 鉴于上述情况,我能否实现,以便它调用并返回返回字符串的长度?也就是说,好像它是: 我天真地尝试了以下方法: 然而,看起来我的想法是错误的,;它看起来像是在生成的实例上调用的。 我还试过一个拦截器: 与: 这运行了,但产生了毫无意义的结果,在中设置断点和/或添加打印语句表明它永远不会被调用;所以很明
我试图捕获一个,其中包含XML规则中不允许使用的字符。(例如,” 我已经阅读了描述方法的Javadoc。但是,我没有看到它无法捕获ValidationEvent。 从指定的InputStream中解组XML数据并返回结果内容树。使用此形式的解组API时,验证事件位置信息可能不完整。 在最后一次尝试中,我尝试在网上搜索,但什么也找不到<任何帮助都将不胜感激:D 我很抱歉补充一个问题。(POJO类有点
我正在测试一个包含多个webview/页面的webview应用程序。为了获得webviews,我做了以下工作: 它返回一个窗口索引数组,这些索引数组类似于
我正在开发一个具有蓝牙功能的应用程序。我使用一个片段来扫描并列出蓝牙设备。单击时,会回调到提供所选蓝牙设备的主要活动。 我一开始使用的是Android 6(API 23)的智能手机,然后不得不调整代码以适应Android 5.0(API 21)的使用。 我只是将minSDK更改为API21并重新构建了项目,没有任何问题。 该应用程序在智能手机上运行时没有任何问题。安装了Android5的平板电脑运
我是Android的新手,我正在开发一个应用程序,该应用程序试图连接服务器并获取Json响应,将其解析为类并使其可用。 为此,我上了三门课 公共类顾客{} 公共类ServerConnect{} 公共类JsonParser{} Serverconnect使用Volley库在异步线程上下载网页源代码。下载后,Server Connect类启动OnServerResponsed(String Respo
本文向大家介绍python使用suds调用webservice接口的方法,包括了python使用suds调用webservice接口的方法的使用技巧和注意事项,需要的朋友参考一下 最近做接口对接,遇到了.net开发的webservice接口,因为python第一次与webservice对接,连问带查,最后使用suds库来实现了 1.安装suds mac: sudo pip install su