6 Replies Latest reply: Oct 7, 2009 6:32 AM by JoachimSauer RSS

    Anonymous class from interface with arguments

    807580
      Hi all, after decompiling a foreign piece of code for debugging purposes - I came up with next method:

      public void do(Executor executor, Event event, Listener listener) {
           executor.execute(new Runnable(listener, event) {
                public void run() {
                     this.val$l.onNotification(this.val$event);
                }
           });
      }

      Since java.lang.Runnable is an interface, I wonder how the original code would be. Arguments should not be there though, and I cannot figure out how to pass them in clean coding.
      Thanks.
        • 1. Re: Anonymous class from interface with arguments
          807580
          Anonymous Inner Class

          http://www.tek-tips.com/faqs.cfm?fid=1849
          • 2. Re: Anonymous class from interface with arguments
            807580
            Thanks. I still miss any example concerning implementing an interface and passing arguments. Usual interface examples have no arguments.
            My decompiled fragment does not compile since it is assumed to extend Object, which constructor takes no args.
            • 3. Re: Anonymous class from interface with arguments
              JoachimSauer
              My guess is that the decompiler does a poor job of reconstructing the original Java code.

              Read [what the JLS says on constructors for anonymous classes|http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.9.5.1]. There are constructors, but they are auto-generated.

              I think the original code will probably look something like this:
              public void do(final Executor executor, final Event event, final Listener listener) {
                executor.execute(new Runnable() {
                  public void run() {
                    listener.onNotification(event);
                  }
                });
              }
              (And please use the CODE-Button when posting code)

              Edit: reviewing this I think that that code never was Java source code to begin with. The name "do" is not a valid name for a Java method, so I now suspect that some tool wrote the byte code directly and never produced Java source code to begin with.
              • 4. Re: Anonymous class from interface with arguments
                800268
                It looks to me the decompiler doesn't handle the anonymous inner class correctly wrt to final variables. The original code was most likely:
                public void do(Executor executor, final Event event, final Listener listener) {
                  executor.execute(new Runnable() {
                    public void run() {
                      listener.onNotification(event);
                    }
                  });
                }
                but it is 'desugared' by the compiler to (guessed, didn't look at the actual byte code):
                public void do(Executor executor, final Event event, final Listener listener) {
                  Outer$1 inner = new Outer$1(this, event, listener);
                  executor.execute(inner);
                }
                
                private class Outer$1 implements Runnable {
                  final synthetic Outer this$0;
                  private final synthetic Event val$event;
                  private final synthetic Listener val$l;
                 
                  private Outer$1(Outer outer, Event event, Listener l) {
                    this$0 = outer;
                    val$event = event;
                    val$l = l;
                  }
                 
                  public void run() {
                    this.val$l.onNotification(this.val$event);
                  }
                }
                Edit: did take a look at the byte code (Eclipse compiler) and the final variables are passed through the constructor which makes more sense with the decompiler result)
                • 5. Re: Anonymous class from interface with arguments
                  EJP
                  Or else the compiler 'sugared' that original syntax into what was decompiled ...
                  • 6. Re: Anonymous class from interface with arguments
                    807580
                    Thank you all. Indeed the solution was located into the capability by the anonymous class to access local variables of the enclosing class (listener, event). I was confused by the decompiler output (btw jd-gui.exe).
                    Now it's clear.