java多个枚举与一个枚举
我正在看反应流规范的Publisher(AsyncIterablePublisher.java)的示例实现,突然发现了一些我不明白为什么会这样做的事情
static interface Signal {};
enum Cancel implements Signal { Instance; };
enum Subscribe implements Signal { Instance; };
enum Send implements Signal { Instance; };
现实一点,我并不像写这篇文章的那个人那样是一个高级程序员,我确信这样做是有原因的。但我也无法解释为什么这样做会比这样做更好(我本来会这样做的)
enum Signal {
Cancel,
Subscribe,
Send;
}
有人能给我解释一下为什么会更好吗?优点/缺点
# 1 楼答案
对于AsyncIterablePublisher中的使用类型,这两种形式是等效的,可以说后者(一个枚举包含多个常量)更自然
事实上,前者非常罕见。我可以看到一个支持使用它的论据(但它非常罕见,这意味着这一点通常不那么重要):当你在自己的枚举中定义每个常量时,你有机会定义不同的方法/字段,例如:
所以你现在可以做
Send.Instance.someSendSpecificMethod()
。非常尴尬,非常罕见# 2 楼答案
不同之处在于,您可以在不更改原始枚举的情况下添加另一个Signal实例。您的代码可以处理信号实例,并且可以提供不同的类型。与类的接口相同,它提供了灵活性,但只有在需要时才有用。在你的例子中,我看不出有多大用处,因为接口是空的,而实现它的枚举中没有任何内容
你可以在这个网站上查看一个很好的enum接口示例:
http://www.selikoff.net/2011/06/15/java-enums-can-implement-interfaces/
# 3 楼答案
不要太严格,以下是我对这条代码的解释。让我们给罗兰的主人打电话
首先,罗兰需要一个通用的界面来支持所有人
像
Cancel
、Subscribe
和Send
这样的信号都有相同的用途,它们是不可变的,并且经常出现,因此最好将它们实现为Joshua Bloch's Singleton:另一种方法类似于你的建议和我最喜欢的:
正如您所看到的,这是一个不同的实现。但这一想法与singleton的想法是一样的
我们继续前进,找到以下代码:
由于
inboundSignals
可以包含多个Request
对象,因此不可能将这种类型的信号实现为单例。因此,它不能是CommonSignals
的成员或实现为enum
结论
罗兰使用了多种可能性中的一种来实现一个单例。我认为这更多的是一个品味的问题,如何做到这一点
# 4 楼答案
所以,因为我不知道应该批准哪一个答案,我把这段代码的作者发了邮件,问他对这段代码的看法。以下是对话(block的是他的,普通文本是我的):
那么,只有一个枚举有什么区别呢?您不会有三个单例,但仍然有三个唯一定义的对象:
我认为这也是线程安全的,如果你真的想拥有共享接口,比如你可以与对象共享,你可以这样做:
实际上,在Scala中,您更愿意使用对象来实现,但在Java中,很少看到类似于您的实现的东西。我只是好奇,我错过了Java中一些简洁的特性。但如果我理解正确的话,那是因为您更容易接受该实现,因为它更接近您的首选语言Scala
谜团解开了:-)
# 5 楼答案
我认为使用enum接口的唯一原因是,一些信号的数据与其他信号不同,因此他需要扩展enum类型以将数据附加到它