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:反思抽象类型的内部类