Scala 反射:强制初始化对象成员 [英] Scala reflection: Force init of object members
本文介绍了Scala 反射:强制初始化对象成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
Scala fiddle 这里
import scala.reflect.ClassTag
import scala.language.existentials
class SomeClass[T <: SomeClass[T, R], R] extends EarlyInit[T, R] {}
trait EarlyInit[T <: SomeClass[T, R], R] {
self: SomeClass[T, R] =>
val clazz = getClass.getSuperclass
val potentialFields = clazz.getDeclaredClasses.toList
potentialFields.foreach {
field => {
// This correctly prints out fields of object members.
// but invokation throws an error every time.
println(s"${field.getName}")
}
}
}
class SomeThing extends SomeClass[SomeThing, Any] {
val stringTest = "test"
object name
object test
}
object SomeThing extends SomeThing {}
val x = SomeThing
如何使用反射访问和初始化对象成员(name
和 test
)?
How do I access and initialise object members(name
and test
) with reflection?
推荐答案
您可以使用 Scala 反射 API 来实现:
You can achieve this with scala reflection API:
import scala.reflect.runtime.universe._
class SomeClass[T <: SomeClass[T, R]: TypeTag, R] extends EarlyInit[T] {}
class EarlyInit[T: TypeTag] {
val mirror = runtimeMirror(this.getClass.getClassLoader)
val reflection = mirror.reflect(this)
typeTag[T].tpe.members.filter(_.isModule).foreach(m => reflection.reflectModule(m.asModule).instance)
}
class SomeThing extends SomeClass[SomeThing, Any] {
val stringTest = "test"
object name {
println("name initialized")
}
object test {
println("test initialized")
}
}
object SomeThing extends SomeThing {}
val x = SomeThing
您需要使 EarlyInit
成为一个类才能获得 TypeTag
证据.然后你只需搜索所有模块并访问它们(它们将在过程中初始化)
You need to make EarlyInit
a class in order to be able to get a TypeTag
evidence. Then you just search for all modules and access them (they would be initialized in the process)
您还可以稍微简化 EarlyInit
并去掉类型参数.你实际上可以直接从镜像中获取this
的Type
:
You can also simplify EarlyInit
a bit and get rid of type parameter. You actually can get a Type
of this
directly from mirror:
trait EarlyInit {
val mirror = runtimeMirror(this.getClass.getClassLoader)
val reflection = mirror.reflect(this)
mirror
.classSymbol(this.getClass)
.toType
.members
.filter(_.isModule)
.foreach(m => reflection.reflectModule(m.asModule).instance)
}
这篇关于Scala 反射:强制初始化对象成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文