scala: reflection on an inner class of abstract type
I want to reflect an inner class of abstract type in a trait. Something like this:
import scala.reflect.runtime.{ universe => ru }
import scala.reflect.ClassTag
import scala.reflect.api.JavaUniverse
import scala.collection.mutable.HashMap
trait SimElement {
type Probe
var probe: Probe
def reflectProbe(implicit ev1: scala.reflect.runtime.universe.TypeTag[Probe]) {
val runtimeMirror: ru.type#Mirror = ru.runtimeMirror(this.probe.getClass.getClassLoader)
val instanceMirror = runtimeMirror.reflect(this.probe.getClass())
val fieldTerm: ru.type#TermName = ru.TermName("name")
println(fieldTerm.toString())
val fieldSymbol = ru.typeOf[Probe].decl(fieldTerm)
println(fieldSymbol.toString())
}
}
class WorldProbe {
var population: Long = 8000000000L
}
class World extends SimElement {
type Probe = WorldProbe
var probe: Probe = new WorldProbe
}
class CountryProbe {
// to be set for every country
var population: Int = 0
// to be set for every country
var name: String = ""
}
class Country extends SimElement {
type Probe = CountryProbe
var probe: Probe = new CountryProbe
}
// ...
val elements: List[SimElement] = List(new World, new Country)
var countries: List[SimElement] = List()
var c1: Country = new Country
c1.probe.name = "Germany"
c1.probe.population = 81000000
var c2: Country = new Country
c2.probe.name = "Netherlands"
c2.probe.population = 16000000
countries = countries.+:(c1)
countries = countries.+:(c2)
elements.foreach { (s: SimElement) => s.reflectProbe }
countries.foreach { (s: SimElement) => s.reflectProbe }
This compiles, but it dosen't work as expected, it prints: name < none > name < none > name < none > name < none >
I think I'm not getting my hand on the "right" object here, however, researching quite a bit did not lead to an answer. Any help?
Thanks!
Found the following solution which is based on the fact that the types for reflection can be stored in the class explicitly:
trait SimElement {
type Probe
var probe: Probe
val probeTypeTag: ru.TypeTag[Probe]
val probeClassTag: scala.reflect.ClassTag[Probe]
val typeSave: reflect.runtime.universe.Type
val typeSaveProbe: reflect.runtime.universe.Type
def reflectTest (implicit ev: scala.reflect.ClassTag[Probe] = probeClassTag) {
val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader)
val im2 = runtimeMirror.reflect(this.probe)
val fieldX2 = typeSaveProbe.declaration(ru.newTermName("name")).asTerm.accessed.asTerm
val fmX2 = im2.reflectField(fieldX2)
val x4= fmX2.get.asInstanceOf[String]
println("reflection result: " + x4)
}
}
class WorldProbe {
var population: Long = 8000000000L
}
class World extends SimElement {
type Probe = WorldProbe
var probe: Probe = new WorldProbe
val probeTypeTag: ru.TypeTag[WorldProbe] = ru.typeTag[WorldProbe]
val probeClassTag: scala.reflect.ClassTag[WorldProbe] = scala.reflect.classTag[WorldProbe]
val typeSave = ru.typeOf[World]
val typeSaveProbe = ru.typeOf[WorldProbe]
}
class CountryProbe {
// to be set for every country
var population: Int = 0
// to be set for every country
var name: String = ""
}
class Country extends SimElement {
type Probe = CountryProbe
var probe: Probe = new CountryProbe
val probeTypeTag: ru.TypeTag[CountryProbe] = ru.typeTag[CountryProbe]
val probeClassTag: scala.reflect.ClassTag[CountryProbe] = scala.reflect.classTag[CountryProbe]
val typeSave = ru.typeOf[Country]
val typeSaveProbe = ru.typeOf[CountryProbe]
}
// ...
val features: List[SimElement] = List(new World, new Country)
var countries: List[SimElement] = List()
var c1: Country = new Country
c1.probe.name = "Germany"
c1.probe.population = 81000000
var c2: Country = new Country
c2.probe.name = "Netherlands"
c2.probe.population = 16000000
countries = countries.+:(c1)
countries = countries.+:(c2)
countries.foreach { (s: SimElement) => s.reflectTest }
Any comments or better suggestions welcome.
Thanks!
链接地址: http://www.djcxy.com/p/76528.html上一篇: 在同伴对象中定义或作为内部类
下一篇: scala:反思抽象类型的内部类