-1

我看到典型的 addXXXListener() 返回 void !无论是 UI 框架(如 Swing)还是服务器端框架,我都认为这是一种全面的实践。

例如:类:AsyncContext

public void addAsyncListener(AsyncListener listener);

类:抽象按钮

public void addActionListener(ActionListener l)

还有许多其他的例子......

我们是否应该有兴趣知道添加侦听器调用是否成功完成?如果组件处于无法添加侦听器的状态怎么办?

例如:考虑 Guava 库 [ListenableFuture]( http://guava-libraries.googlecode.com/svn/tags/release08/javadoc/com/google/common/util/concurrent/ListenableFuture.html#addListener(java.lang .Runnable , java.util.concurrent.Executor))

它有一个

void addListener(Runnable listener, Executor exec);

它的行为是当 Future 的计算完成时执行监听器。他们采用的方法是,如果 Future 已经完成,那么侦听器将立即被调用。即使未来已经完成了很久。没有迹象表明他们在已经完成的未来不必要地调用 addListener() !

我认为 addListener() 应该能够返回一个值(布尔值?),说明是否可以成功添加侦听器,如果无法添加侦听器,则让调用者进行处理!

我知道所有 addListener 都以这种方式编写一定是有原因的。我只是不知道为什么?

4

3 回答 3

5

这些方法通常只是将您的侦听器添加到列表中。它不起作用的情况通常不在您的控制范围内(例如,考虑内存不足错误)并且无论如何都会触发异常。

例如,返回布尔值的原因Collection#add是某些实现仅在满足某些条件时才添加该项目(例如,如果它是重复的,Sets 将不会添加一个项目)。请注意,这是唯一Collection#add会返回 false的情况(其他原因会触发异常):

如果一个集合拒绝添加一个特定元素,除了它已经包含该元素之外,它必须抛出一个异常(而不是返回 false)。这保留了在此调用返回后集合始终包含指定元素的不变量。

这可能被认为对addListener.

于 2013-05-10T18:18:42.827 回答
1

在所有这些情况下,不可能无法添加侦听器。

即使未来已经完成了很久。

那么,如果未来在很久以前就完成了呢?如果你想在 中添加一个监听器Future,你想在结果完成时对它做一些事情,无论是很久以前还是将来。

于 2013-05-10T18:18:01.623 回答
1

如果可以期望调用者对信息采取行动,则约定是向调用者返回信息。

ListenableFuture 与大多数 addXXXListener() 调用是一个非常不同的用例。这些预计会立即返回并在正常操作中 100% 成功(例如,只是将侦听器添加到某些内部列表结构)并且没有可操作的信息返回给调用者。(但是,在非正常操作中,您可能希望它抛出未经检查的异常)。

如果内部数据结构已被 addXXXListener() 调用修改,则一种可能的变体是将其视为 mutator 操作并扩展通常的 Collection 模式以返回布尔值。虽然这只会在调用者不知道它是否已经添加自己的情况下返回有用的信息......

于 2013-05-10T18:21:02.287 回答