Estou escrevendo um serializador personalizado para classes de caso Scala e tenho uma função utilitária para determinar se vários símbolos são classes de caso:
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)
As isInstanceOf
verificações levam a avisos, mas não sei por quê:
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
Eu entendo a eliminação de tipo quando genéricos estão envolvidos, por exemplo, JVM não consegue distinguir List[Integer]
de List[String]
e entramos no reino das tags de tipo para classificar esses tipos de problemas. Mas no meu caso MethodSymbol
é uma subclasse de Symbol
então por que a eliminação de tipo?
Alguém poderia gentilmente explicar?
Obrigado,
Davi
Conforme levantado em um comentário, eu originalmente sugeriria que isso é causado pelo uso de conversão de tipos, mas alterar o código para usar correspondência de padrões não ajudou:
O aviso ainda está lá, mas eu ainda recomendaria, em geral, usar correspondência de padrões em vez de
isInstanceOf
/asInstanceOf
(lembro-me do criador do Scala, Martin Odersky, mencionando em seu livro "Princípios de Programação Funcional em Scala" no Coursera que ele tornou o par prolixo de propósito para incentivar as pessoas a usar a correspondência de padrões).Não tenho 100% de certeza sobre o motivo específico pelo qual o aviso aparece neste contexto, mas uma possível explicação é que a coisa real apoiada pelo
Symbol
próprio pode aparecer em um contexto genérico, o que significa que é um parâmetro para uma classe genérica. Como tal, o compilador não pode garantir que a implementação concreta deSymbol
seja capturada em tempo de execução, levando ao aviso.Como solução alternativa, se você não se importar que essas informações não sejam capturadas caso apareçam como um argumento genérico, você pode marcar os tipos da
@unchecked
seguinte forma:Você pode brincar com esse código aqui no Scastie .