La réflexion est connu pour avoir des problèmes avec le symbole init et aussi le manque de sécurité des threads. Peut-être que c'est ainsi que vous élicitez le symptôme.
Montrer que le code d'origine fonctionne:
$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
Type in expressions for evaluation. Or try :help.
scala> object FunninessLevel extends Enumeration {
| type FunninessLevel = Value
| val LOL, ROFL, LMAO = Value
| }
defined object FunninessLevel
scala>
scala> :pa
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime.universe._
/**
* Scala [[Enumeration]] helpers implementing Scala versions of
* Java's [[java.lang.Enum.valueOf(Class[Enum], String)]].
* @author Dmitriy Yefremov
*/
object EnumReflector {
private val mirror: Mirror = runtimeMirror(getClass.getClassLoader)
/**
* Returns a value of the specified enumeration with the given name.
* @param name value name
* @tparam T enumeration type
* @return enumeration value, see [[scala.Enumeration.withName(String)]]
*/
def withName[T <: Enumeration#Value: TypeTag](name: String): T = {
typeOf[T] match {
case valueType @ TypeRef(enumType, _, _) =>
val methodSymbol = factoryMethodSymbol(enumType)
val moduleSymbol = enumType.termSymbol.asModule
reflect(moduleSymbol, methodSymbol)(name).asInstanceOf[T]
}
}
/**
* Returns a value of the specified enumeration with the given name.
* @param clazz enumeration class
* @param name value name
* @return enumeration value, see [[scala.Enumeration#withName(String)]]
*/
def withName(clazz: Class[_], name: String): Enumeration#Value = {
val classSymbol = mirror.classSymbol(clazz)
val methodSymbol = factoryMethodSymbol(classSymbol.toType)
val moduleSymbol = classSymbol.companionSymbol.asModule
reflect(moduleSymbol, methodSymbol)(name).asInstanceOf[Enumeration#Value]
}
private def factoryMethodSymbol(enumType: Type): MethodSymbol = {
enumType.member(newTermName("withName")).asMethod
}
private def reflect(module: ModuleSymbol, method: MethodSymbol)(args: Any*): Any = {
val moduleMirror = mirror.reflectModule(module)
val instanceMirror = mirror.reflect(moduleMirror.instance)
instanceMirror.reflectMethod(method)(args:_*)
}
}
// Exiting paste mode, now interpreting.
warning: there were two deprecation warnings; re-run with -deprecation for details
import scala.reflect.runtime.universe._
defined object EnumReflector
scala> val level = EnumReflector.withName(FunninessLevel.getClass, "ROFL")
level: Enumeration#Value = ROFL
Parfois, l'initialisation des forces REPL par accident. Affichage de la ligne de commande:
$ scalac reflect-enum.scala && scala reflect_enum.Test
reflect-enum.scala:45: warning: method companionSymbol in trait SymbolApi is deprecated: Use `companion` instead, but beware of possible changes in behavior
val moduleSymbol = classSymbol.companionSymbol.asModule
^
reflect-enum.scala:50: warning: method newTermName in trait Names is deprecated: Use TermName instead
enumType.member(newTermName("withName")).asMethod
^
two warnings found
ROFL
Le code de blog fonctionne pour moi simplement coller dans REPL. Vous devrez montrer votre travail. –
@ user1875107: passez-vous 'classOf [MyEnum.Value]' (mauvais) au lieu de 'classOf [MyEnum.type]' ou 'MyEnum.getClass' (bien) par hasard? –