Pergunta

I have the following code:

public class Bar {}
public class FooBar {}

public class Foo {

    public void method() {
        new Bar() {

            void otherMethod() { }

            void barMethod() {

                new FooBar() {

                    void fooBarMethod() {
                        Bar.this.otherMethod(); // not compiles
                    }   
                };
            }
        };
    }

}

So i have an anonymous inner class, which has another anonymous inner class in it. The question: is there any way to access the methods of the outer inner class Bar from the inner inner class FooBar?

Foi útil?

Solução

You can call the method directly using simple name:

void fooBarMethod() {
    otherMethod(); // compiles
}

This will fail, the moment you define another method with the name otherMethod() in the new FooBar() anonymous class.

Bar.this wouldn't really work, because that's an anonymous class there, whose name is given at compile time. It will get a name like Foo$1. So, no you can't have something like Bar.this.


Ok, I've written this source file:

class Bar { }

class FooBar { }

public class Demo {

    public static void main() {
        new Demo().method();
    }

    public void method() {
        new Bar() {

            void otherMethod() { System.out.println("Hello"); }

            void barMethod() {

                new FooBar() {

                    void fooBarMethod() {
                        otherMethod(); // not compiles
                    }   
                }.fooBarMethod();
            }
        }.barMethod();
    }
}

The class files generated would be:

Bar.class
FooBar.class
Demo.class

Demo$1.class    // For `new Bar()` anonymous class
Demo$1$1.class  // For `new FooBar()` anonymous class

Now, let's go straight to the byte code of new FooBar() anonymous class. The class will be named - Demo$1$1. So, running the javap command, I get this output:

class Demo$1$1 extends FooBar {
  final Demo$1 this$1;

  Demo$1$1(Demo$1);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1                  // Field this$1:LDemo$1;
       5: aload_0
       6: invokespecial #2                  // Method FooBar."<init>":()V
       9: return

  void fooBarMethod();
    Code:
       0: aload_0
       1: getfield      #1                  // Field this$1:LDemo$1;
       4: invokevirtual #3                  // Method Demo$1.otherMethod:()V
       7: return
}

The final field there is a copy of reference to new Bar() instance. So, the otherMethod() is invoked on this$1 reference, which is a reference to the instance of new Bar() anonymous inner class. Well, you were trying to do that only, but since that's an anonymous inner class, you cannot access the this reference directly. But, that is implicit there.


For more detailed analysis:

Outras dicas

If you name them then they aren't anonymous inner classes, they are just inner classes. If you don't name them then you can't call them explicitly, although you can call them if there is no name conflict.

Your code is completely invalid though, you are creating a new Bar but never defining a class called Bar.

Forget the line you say "not compiles" on, the first "new Bar()" doesn't compile...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top