Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the super method not visible/resolved?

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

like image 372
TWiStErRob Avatar asked Mar 17 '23 17:03

TWiStErRob


2 Answers

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 is T.

  • 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.

like image 124
Sotirios Delimanolis Avatar answered Mar 27 '23 21:03

Sotirios Delimanolis


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.

like image 28
loshad vtapkah Avatar answered Mar 27 '23 19:03

loshad vtapkah