Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8881

Inner class - qualified "this" reference cast exception inside 2 closures

    XMLWordPrintableJSON

Details

    Description

      Let's consider the below example of qualified (Outer class) "this" reference from within the Inner class, used inside a closure defined inside another closure (2 layers of closures):

      class OuterClass implements Runnable {
      
          class InnerClass {
      
              String bar() {
                  Closure closureOne = {
                      Closure closureTwo = {
                          OuterClass outerClassViaQualifiedThisReference = OuterClass.this
                          return outerClassViaQualifiedThisReference
                      }
                      return closureTwo.call()
                  }
                  closureOne.call()
              }
      
          }
      
          String toString() {
              return "OuterClass"
          }
      
          void run() {
              System.out.println(new InnerClass().bar())
          }
      }
      

      It produces the below runtime exception:

      java.lang.ClassCastException: OuterClass$InnerClass cannot be cast to OuterClass$InnerClass$_bar_closure1
      	at OuterClass$InnerClass$_bar_closure1$_closure2.doCall(ConsoleScript279:8)
      	at OuterClass$InnerClass$_bar_closure1$_closure2.doCall(ConsoleScript279)
      	at OuterClass$InnerClass$_bar_closure1.doCall(ConsoleScript279:11)
      	at OuterClass$InnerClass$_bar_closure1.doCall(ConsoleScript279)
      	at OuterClass$InnerClass.bar(ConsoleScript279:13)
      	at OuterClass$InnerClass$bar.call(Unknown Source)
      	at OuterClass.run(ConsoleScript279:23)
      

      However the below code runs fine (if only 1 closure is used):

      class OuterClass implements Runnable {
      
          class InnerClass {
      
              String bar() {
                  Closure closureOne = {
                      //Closure closureTwo = {
                          OuterClass outerClassViaQualifiedThisReference = OuterClass.this
                          return outerClassViaQualifiedThisReference
                      //}
                      //return closureTwo.call()
                  }
                  closureOne.call()
              }
      
          }
      
          String toString() {
              return "OuterClass"
          }
      
          void run() {
              System.out.println(new InnerClass().bar())
          }
      }
      

      Expected result:

      Code should run in both cases without runtime exceptions and should output "OuterClass".

      Attachments

        Activity

          People

            paulk Paul King
            anton.pryamostanov Anton Pryamostanov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: