【发布时间】:2016-08-05 21:29:10
【问题描述】:
我正在编写一个扩展 Java 类的 Scala 类。我必须扩展这个抽象 Java 类,因为它包含一些转换器,并且我需要编写我自己的转换器,我可以插入到他们的框架中。所以下面方法的签名是强加给我的:当我说我的类扩展了它们的抽象类时,它是由 Eclipse 自动生成的。如果我尝试修改方法签名,则该类无法编译,因为“它没有实现父级的抽象方法”。
方法的实现当然是我的选择——但我发现我无法满足类型系统的约束。
我需要做一些非常简单的事情:将“None”视为 null 并按原样返回任何其他内容。但我发现我不能以类型安全的方式做到这一点。如果我编写如下所示的代码,我会收到一条警告说“抽象类型 T 未选中,因为它已被擦除消除”。我怎样才能消除它?
我还想知道我的代码在应用擦除后会是什么样子,即第二个“if”条件会是什么样子。
直观地说,我知道当输入为 Any 时我不能保证返回 T - 这就是编译器不满意的原因。实际上,这会起作用,因为我们只是在读取字符串并返回字符串 - 但是方法签名是由继承声明强加给我的。
def execute[T](value: Any): T = {
if (value == null || value == "None") null.asInstanceOf[T]
// Warning: abstract type T is unchecked since it is eliminated by erasure
else if (value.isInstanceOf[T]) value.asInstanceOf[T]
// warning here: ^
else null.asInstanceOf[T]
}
我该如何实现这个方法?
【问题讨论】:
-
由于擦除将第二个“if”语句转换为“isInstanceOf[Object]”,这始终是正确的,这实际上保证不会按照程序员的意图进行。我很震惊,这是一个警告而不是错误。我意识到这个问题不能以类型安全的方式解决,因为输入是 Any,输出是 T。我从 Alexey 的解决方案中意识到,一旦你开始做这样的事情,你基本上是在告诉编译器“信任我,在运行时这将被强制转换为 T”,编译器的“类型安全保证”变为“我看到程序员承诺了一个 T”。
标签: scala inheritance erasure