我在Scala项目中使用了Guava的EventBus
。
我有一个像这样的参数化事件:
class MyEvent[T]
一个简单的事件监听器:
class MyEventListener {
@Subscribe
def onStringEvent(event: MyEvent[String]) {
println("String event caught")
}
@Subscribe
def onIntEvent(event: MyEvent[Int]) {
println("Int event caught")
}
}
我可以创建我的com.google.common.eventbus.EventBus
,注册MyEventListener
,然后点击一个事件:
val eventBus = new EventBus
eventBus.register(new MyEventListener)
eventBus.post(new MyEvent[String])
但是,正如您可能已经猜到的那样,onStringEvent
和onIntEvent
都会被调用。问题是Java的/ Scala的类型擦除在运行时删除了参数类型,并且两个订阅在Guava中显示为event: MyEvent
。
好的,我的问题:
由于擦除,在Java中不可能以这种方式对不同类型的Guava事件使用相同的Event对象,并且在Scala中是不可能的。但是,Scala证明有许多很好的方法来规避Java的擦除问题。有没有人看到另一种方法来实现这一点,也许使用一些Scala魔法?
答案 0 :(得分:4)
问题在于Guava:它无法看到类型参数,因此它不会区分这两种方法。唯一可行的解决方案是为每种类型创建一个新类。
这真的很容易:
class MyEvent[T] protected () { /* Your methods here */ }
class MyEventInt extends MyEvent[Int] {}
class MyEventString extends MyEvent[String] {}
然后只要您需要在代码中执行任何操作,只需使用MyEvent[Int]
即可。但是番石榴至少需要这么多样板。
请注意,我已使MyEvent[T]
构造函数受到保护,因此您必须实例化一个去泛化的类。我不确定这是否适用于您的用例;我会假设的。你也可以绕过它(使用类型类),但它增加了更多的样板。