【发布时间】:2013-01-07 00:52:05
【问题描述】:
我有一些旧版 Java 代码定义了一个通用的 payload 变量在我无法控制的地方(即我无法更改它的类型):
// Java code
Wrapper<? extends SomeBaseType> payload = ...
我接收这样的 payload 值作为我的代码中的方法参数,并希望将其传递给 Scala case class(用作演员系统的消息),但做没有得到正确的定义,以至于我至少没有收到编译器警告。
// still Java code
ScalaMessage msg = new ScalaMessage(payload);
这会给出编译器警告“类型安全:构造函数...属于原始类型...”
Scala case class 定义为:
// Scala code
case class ScalaMessage[T <: SomeBaseType](payload: Wrapper[T])
如何定义案例类以使代码编译干净? (遗憾的是,更改Java Wrapper 类的代码或payload 参数的类型不是一个选项)
更新以阐明有效载荷的来源参数
添加作为比较,在Java中我可以定义一个参数,就像定义payload变量一样:
// Java code
void doSomethingWith(Wrapper<? extends SomeBaseType> payload) {}
并相应地调用它
// Java code
doSomethingWith(payload)
但我无法实例化例如直接包装对象而不会收到“原始类型”警告。在这里,我需要使用static 辅助方法:
static <T> Wrapper<T> of(T value) {
return new Wrapper<T>(value);
}
并使用此静态助手实例化 Wrapper 对象:
// Java code
MyDerivedType value = ... // constructed elsewhere, actual type is not known!
Wrapper<? extends SomeBaseType> payload = Wrapper.of(value);
解决方案
我可以为 Scala 伴生对象添加一个类似的辅助方法:
// Scala code
object ScalaMessageHelper {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
new ScalaMessage(payload)
}
object ScalaMessageHelper2 {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
ScalaMessage(payload) // uses implicit apply() method of case class
}
并在 Java 中使用它来实例化 ScalaMessage 没有问题的类:
// Java code
ScalaMessage msg = ScalaMessageHelper.apply(payload);
除非有人提出更优雅的解决方案,否则我会提取这个作为答案...
谢谢!
【问题讨论】:
标签: java scala generics types scala-java-interop