Reputation: 1358
In the following code, I noticed that I can call getWorld() without a reference to the HelloWorld object? But doesn't the implicit 'this' keyword now refer to the inner anonymous class? If so, why I am able to call getWorld()?
public class HelloWorld {
public void getWorld() {
this.setListener(new MyListenerInterface(){
@Override
public void innerMethod() {
getWorld();
}
});
}
}
Ignore the recursion in the code.
Upvotes: 0
Views: 382
Reputation: 10613
The answer is in Section 15.12 of the JLS.
If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier.
If the Identifier appears within the scope of a visible method declaration with that name (§6.3, §6.4.1), then:
- If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.
By using just the simple name of the method, the resolution of which method to call looks up through the enclosing methods until it finds one which has a method with that name, and then attempts to use that method (or methods) to find an exact match.
This is different than the case where you use this.getWorld()
, since this
refers unambiguously to the inner class instance. That results in a different type of resolution (the Typename . Identifier
section of the specification, just below the linked quote), which does not look at the enclosing outer class.
An interesting consequence of this is that you can cause the code to stop compiling by adding a method to the inner class which has the same name, but a different arity. Since it only is searching for the name itself when it tries to determine the class instance to resolve it on, it will try to use the inner class, but not find an exact matching method.
So this:
public class HelloWorld {
public void getWorld() {
this.setListener(new MyListenerInterface(){
@Override
public void innerMethod() {
getWorld();
}
void getWorld(int i){}
});
}
}
would not compile. Method name resolution will discover getWorld
in the inner class, and so will stop searching up the hierarchy. But when it tries to do arity resolution, it will see that none of the (one) getWorld
methods in the class match, and will fail.
TL;DR - using just the simple name is note quite the same as using this.method()
, even though it generally evaluates to the same thing. The language specification has specific rules for handling that case, which can allow it to look in any enclosing instance to find a matching method.
Upvotes: 2
Reputation: 27476
Calling getWorld
you get outside the anonymous class and are back at the top level class, so this
refers to the object that is creating the anonymous one.
It is like calling a method from other class, this
there refers to a different object (not to the caller, but to the callee).
Upvotes: 1