Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using reflection to access outer class in Scala

Tags:

scala

In Scala, is it possible to use reflection to access the outer class of an inner class? For example:

class A { 
   val inner = new { 
      println(getClass.getConstructors.toList)  
      println(getClass.getDeclaredFields.toList)
   }
}

scala> val a = new A
List(public $line11.$read$$iw$$iw$A$$anon$1($line11.$read$$iw$$iw$A))
List()
a: A = A@45f76fc7

I think that the Scala compiler saves a reference to the outer class somewhere, but you can see here that the list of fields printed in the constructor is empty. Also, it looks like the constructor takes a reference to the outer class instance (but it's hard to tell for sure --- I'm not sure exactly what's going on here). I have also noticed in some cases there is an $outer field that seems to be what I need, but it it's not always there, and I don't understand this.

WHY???!!! I have an inner class that I need to create a new instance of using reflection. The new instance is being copied from an existing instance, and needs to have the same outer reference.

like image 769
Landon Kuhn Avatar asked Dec 10 '22 06:12

Landon Kuhn


1 Answers

I don't think you can reliably get the parent unless you use the parent outside the constructor if the inner class. Given:

class X  {
    val str = "xxyy"
    val self = this

    val inner = new {
        override def toString():String = {
            "inner " + self.toString
        }

    }

    override def toString():String = {
        "ima x" + this.str
    }

}

If you do javap you get a private field $outer

but given:

class X  {
    val str = "xxyy"
    val self = this

    val inner = new {
        println(self)

    }

    override def toString():String = {
        "ima x" + this.str
    }

}

The javap does not indicate the $outer field.

like image 179
agilefall Avatar answered Dec 25 '22 15:12

agilefall