Reputation: 46480
interface Problematic {
void method();
}
class Parent {
void method(int arg) { }
}
class Child extends Parent {
void test() {
new Problematic() {
@Override public void method() {
// javac error: method method in class <anonymous Problematic> cannot be applied to given types;
// required: no arguments, found: int
method(0);
Child.this.method(0); // works just fine
Child.super.method(0); // works just fine
}
};
}
}
IntelliJ IDEA also gives a warning:
Method 'method()' recurses infinitely, and can only end by throwing an exception
Upvotes: 4
Views: 987
Reputation: 311023
An overload in a child class hides the method being overloaded in the parent class. In this case, Problematic.method()
overloads and hides Parent.method(int).
Upvotes: 1
Reputation: 280138
From the Java Language Specification,
If the form is
MethodName
, that is, just an Identifier, then:If the Identifier appears in 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 isT
.This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See §6.5.7.1 for an example.
Otherwise, the visible method declaration may be in scope due to one or more single-static-import or static-import-on-demand declarations. There is no class or interface to search, as the method to be invoked is determined later (§15.12.2.1).
You're invoking the method inside the anonymous inner class which is a subtype of Problematic
. This makes Child
its enclosing type. In your case, T
is the anonymous inner class, since that is the innermost type. Because of this, the class to search for the method is T
, ie. the anonymous subclass of Problematic
.
In later steps of the resolution of method invocation expressions, it is decided that the method Problematic#method()
takes no arguments since it declares no parameters. It is therefore not applicable and a compiler error is raised.
Upvotes: 4
Reputation:
method(0)
is actually this.method(0)
which is actually Child$1.this.method(0)
and Child$1.this.method(int)
does not exist in the declaration of Problematic
.
This is explained in the error messages from the compiler and from the IDE.
The compiler tells you that this is exactly what it is doing, it is resolving to the most local scope and finding something and that something isn't correct and it stops looking.
@Override public void method() {
// javac error: method method in class <anonymous Problematic> cannot be applied to given types;
// required: no arguments, found: int
method(0);
Child.this.method(0); // works just fine
Child.super.method(0); // works just fine
}
@Override public void method() {
// javac error: method method in class <anonymous Problematic> cannot be applied to given types;
// required: no arguments, found: int
this.method(0); // this is implied in the above code
// and resolves to the Problematic declaration
Child.this.method(0); // will never be reached if the previous call is actually corrected.
Child.super.method(0); // will never be reached either
}
this.method(0)
is invalid code and if you called this.method()
it would just recurse infinitely and throw a StackOverflow
error.
This is explained in the error messages from the compiler and from the IDE.
This is how the scope resolution works, there is no mystery why, read the scope resolution rules and you will see it looks for this.XXX
first then broadens the scope.
If your goal is to call method(int)
on Child
you already know how to do that, you have to call it with Child.this.method(int)
, it has to be fully qualified because of the namespace scoping resolution.
Upvotes: 0
Reputation: 459
See https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html:
Shadowing
If a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope.
Upvotes: 2