Scala 抽象类型T被取消选中,因为它是通过擦除消除的
我正在编写一个扩展Java类的Scala类。我必须扩展这个抽象Java类,因为它包含一些转换器,我需要自己编写一个转换器,可以插入到它们的框架中。因此,下面方法的签名是强加给我的:当我说我的类扩展了它们的抽象类时,它是由Eclipse自动生成的。如果我试图修改方法签名,该类将无法编译,因为“它没有从父级实现抽象方法” 当然,方法的实现是我的选择——但我发现我无法满足类型系统的约束 我需要做一些非常简单的事情:将“None”视为null,并按原样返回任何其他内容。但是我发现我不能用类型安全的方式来做这件事。如果我按如下所示编写代码,我会收到一条警告,说“抽象类型T未选中,因为它已通过擦除消除”。我怎样才能消除这种情况 我还想知道,一旦应用擦除,我的代码会是什么样子,即第二个“如果”条件会是什么样子 直觉上,我知道我不能保证在输入为Any时返回T,这就是编译器不高兴的原因。实际上,这是可行的,因为我们只是读取字符串并返回字符串——但是继承声明将方法签名强加给我Scala 抽象类型T被取消选中,因为它是通过擦除消除的,scala,inheritance,erasure,Scala,Inheritance,Erasure,我正在编写一个扩展Java类的Scala类。我必须扩展这个抽象Java类,因为它包含一些转换器,我需要自己编写一个转换器,可以插入到它们的框架中。因此,下面方法的签名是强加给我的:当我说我的类扩展了它们的抽象类时,它是由Eclipse自动生成的。如果我试图修改方法签名,该类将无法编译,因为“它没有从父级实现抽象方法” 当然,方法的实现是我的选择——但我发现我无法满足类型系统的约束 我需要做一些非常简单的事情:将“None”视为null,并按原样返回任何其他内容。但是我发现我不能用类型安全的方式来
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]
}
如何实现此方法?最后,我可以做以下两件事之一:
谢谢亚历克的建议 您的Java解决方案不包含t的测试
值实例,因此您不需要在Scala解决方案中安装[t]
。您应该删除它,因为该检查不起任何作用:它会擦除到isInstanceOf[Object]
,这始终是真的,因此不会执行最后一个else
分支。剩下的区别是,在Java中,您将String.valueOf(value)
与“None”
进行比较,而不是value
本身。因此,Java解决方案的等价物是
def execute[T](value: Any): T = {
(if (value == null || String.valueOf(value) == "None") null else value).asInstanceOf[T]
}
根据String.valueOf
的定义,可以将条件简化为value==null | | value.toString==“无”
在我看来,编译器应该针对asInstanceOf[T]
发出警告,而不仅仅是针对isInstanceOf[T]
;在这种情况下,Java实际上比Scala更安全,因为1)它确实为强制转换提供了警告;2) instanceof
检查将是一个错误而不是警告
作为旁注,虽然您可以消除警告,但如果出现这样一个带有签名的方法,则强烈表明作者对Java泛型的理解不够透彻,我会非常小心地使用该库。也许这会有所帮助:。因为擦除会将第二个“if”语句变成“isInstanceOf[Object]”,这总是正确的,这实际上保证不会做程序员想要做的事情。我感到震惊的是,这是一个警告,而不是一个错误。我意识到这个问题不能用类型安全的方式解决,因为输入是Any,输出是T。我从Alexey的解决方案中意识到,一旦你开始做这样的事情,你基本上是在告诉编译器“相信我,在运行时这将被强制转换为T”,编译器的“类型安全保证”变成了“我看到程序员承诺了一个T“.那是你想要的吗?你所做的只是抑制警告…擦除仍然会得到你。如果你不能添加
ClassTag
或Manifest
,你可能是SOL,必须使用Java实现。如果我看一下Java代码,我肯定它能做我想要的,因为我了解它的功能。几乎没有一个实现依赖于T。最后的cast可以忽略,我仍然得到了我想要的。在Scala中,我不明白擦除后第二个if语句变成了什么。我必须进行测试。因为我已经删除了我的答案(因为OP不能添加ClassTag
或Manifest
),所以答案就在这里,供将来参考def execute[t:ClassTag](value:Any):t=value match{case“None”=>null.asInstanceOf[t]case x:t=>x case\u=>null.asInstanceOf[t]}