2013-05-10 58 views
-1

我看到一个典型的addXXXListener()返回void! 我认为这是一种全面的做法,无论是UI框架(如Swing)还是服务器端框架。为什么addListener()通常返回void?

对于前: 类:AsyncContext

public void addAsyncListener(AsyncListener listener); 

类:AbstractButton

public void addActionListener(ActionListener l) 

和许多其他例子...

不应该我们有兴趣知道,如果添加监听通话成功完成? 如果组件处于无法添加侦听器的状态,该怎么办?

对于离:考虑番石榴库[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); 

它的行为是,收听者被执行时未来的计算已完成。 他们采取的方法是,如果未来已经完成,那么听众将立即被调用。即使未来已经完成了。 没有任何迹象表明他们在未完成的未来不必要地调用addListener()!

我会认为addListener()应该能够返回一个值(boolean?),它表示如果可以成功添加侦听器并让调用者在侦听器无法添加时执行处理!

我知道为什么所有addListeners都是这样写的。 我只是不知道为什么?

回答

5

这些方法通常只需将侦听器添加到列表中。无法工作的情况一般在你的控制范围之外(例如,考虑到内存错误),并且无论如何都会触发异常。

例如,Collection#add返回布尔值的原因是,某些实现只会在满足某些条件时才添加项目(例如,如果项目是重复的,则不会添加项目)。需要注意的是this is the only situation when Collection#add will return false(其他原因,将触发异常):

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

这可能被认为对addListener不是很有用。

+2

回答真的是一门艺术。感谢这样写得很好(但很短)的答案。 – brainOverflow 2013-05-10 18:56:30

1

在所有这些情况下,听众可能无法添加失败。

即使未来完成了年龄的回来。

那么未来如何完成呢?如果您想要将收听者添加到Future,您希望在完成时使用该结果进行处理,无论这是在很久以前还是将来。

+0

确定。这是问题。假设我有一个CustomFuture并且我的侦听器接口有两个方法:onStart()和onComplete()。当我做一个addListener(侦听器);在一个已经完成的Future上,你认为onStart()应该再次被调用?还有onComplete()? – brainOverflow 2013-05-10 19:27:22

+0

我认为你需要决定的是你自己的'CustomFuture'接口。 – 2013-05-10 20:08:16

+0

是我决定的课程。我只是试图从addListener()返回一个结果。这确实取决于用例。没关系。 – brainOverflow 2013-05-10 20:46:28

1

的惯例是将信息返回给调用者如果调用者可以预期采取行动的信息。

的ListenableFuture是一个非常不同的使用情况,以最addXXXListener()调用。这些预期立即返回,并在正常操作100%成功(例如只是添加监听到一些内部列表结构)并没有可操作的信息返回给调用者。 (但是,在非正常操作中,您可能会期望它会抛出未经检查的异常)。

一种可能的变化是其视为突变操作,并延长通常的收集模式,如果内部数据结构已被addXXXListener()调用修改以返回一个布尔值。虽然这只是返回有用的信息如果主叫方不知道它是否已经添加自己...