我正在为 Scala 案例类编写一个自定义序列化器,并有一个实用函数来确定各种符号是否是案例类:
import scala.reflect.runtime.{universe => ru}
def isCaseClass(symbol: ru.Symbol): Boolean = (symbol.isInstanceOf[ru.MethodSymbol] &&
symbol.asInstanceOf[ru.MethodSymbol].isCaseAccessor) ||
(symbol.isInstanceOf[ru.ClassSymbol] &&
symbol.asInstanceOf[ru.ClassSymbol].isCaseClass)
检查isInstanceOf
导致警告,但我不知道为什么:
abstract type reflect.runtime.universe.MethodSymbol is unchecked since it is eliminated by erasure
abstract type reflect.runtime.universe.ClassSymbol is unchecked since it is eliminated by erasure
我理解当涉及泛型时的类型擦除,例如 JVM 无法区分List[Integer]
,List[String]
我们进入类型标记领域来解决这些问题。但在我的例子中MethodSymbol
是的子类,Symbol
那么为什么要进行类型擦除呢?
有人可以解释一下吗?
谢谢,
大卫
正如评论中提出的,我原本想提出这是由使用类型转换引起的,但将代码更改为使用模式匹配并没有帮助:
警告仍然存在,但我通常仍建议使用模式匹配而不是
isInstanceOf
/asInstanceOf
(我记得 Scala 的创建者 Martin Odersky 在 Coursera 上的“Scala 函数式编程原理”中提到,他故意使该对变得冗长,以激励人们使用模式匹配)。我不能 100% 确定警告在此上下文中出现的具体原因,但一种可能的解释是,本身支持的实际内容可能出现在通用上下文中,这意味着它是通用类的参数。因此,编译器无法保证在运行时捕获的具体实现,从而导致警告。
Symbol
Symbol
@unchecked
作为一种解决方法,如果您不同意这些信息在作为通用参数出现时不被捕获,那么您可以按如下方式标记类型:您可以在 Scastie 上试用此代码。