将Runnable用作回调/子例程是一种不良实践吗?

14

Runnable用作回调是否被认为是不良实践?

考虑到Runnable应该与线程一起使用(请参见其JavaDoc),我想知道这样做是否可以 - 或者我是否应该为此目的创建自己的接口。

我在谈论什么是这样的:

public class KeyBinding {
    public KeyBinding(KeyStroke stroke, Runnable handler) {
        //...
    }
}
2个回答

27

不要将Runnable用作回调函数;这可能会导致混乱:有些人和代码质量工具仅将其用于线程。

我曾经使用过Runnable作为回调函数,我认为它似乎非常适合用作通用回调。一个月后,有人找到了我的代码片段:

doneCallback.run();

他注意到doneCallback是一个Runnable,而直接调用.run()会导致我们的代码质量分析程序(Sonar)发出警告。所以,为了修复这个警告?还是因为他认为意图是创建一个线程?他叉了一个新线程,并通过该线程调用run()

然而,在那里叉线程破坏了东西。

为避免混淆,现在我正在创建一个通用的回调接口,与任何线程都无关。我只需添加一个名为Callback的类和一个名为call的方法即可。我认为最好不要使用java.util.concurrent.Callback,因为那个与线程有关。


1
这真的很有帮助!非常感谢 ^^ - Anis LOUNIS aka AnixPasBesoin

7

实际上,Runnables可以用于任何目的。

“方法run的一般契约是它可能采取任何行动” (Runnable javadoc)

通常来说,这不应该是一个不好的做法,绝对比在你自己的代码中创建一个额外的不必要的接口更好的做法。


3
另一方面,看到您提供的文档链接,它说“应该由任何其实例旨在由线程执行的类来实现Runnable接口。”因此,就像KajMagnus所经历的那样,人们可能会期望将Runnable与线程关联起来,并发现这种用法令人困惑。我同意KajMagnus的观点,定义一个特定于此用途的接口更清晰。 - ToolmakerSteve
3
实际上,它始终与一个线程相关联,即主线程! - Hugo Baés

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接