Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner classes with method names and different signatures than the outer class

I know how to get this code to work, but I'm curious why the compiler is not able to figure out that the call is to the outer class method:

public class Example {
    public void doSomething(int a, int b)
    {
    }

    public class Request
    {
        public int a;
        public int b;

        public void doSomething()
        {
            doSomething(a,b); // Error. Fix: Example.this.doSomething(a,b);
        }
    }
}

Is there a deeper design reason for this than protecting coders from making mistakes?

like image 412
Thomas Andrews Avatar asked Sep 29 '11 16:09

Thomas Andrews


People also ask

Can an inner class use methods of an outer class?

Inner classes can access the variables of the outer class, including the private instance variables. Unlike the non-static nested classes, the static nested class cannot directly access the instance variables or methods of the outer class.

What is method inner class?

Local Inner Classes are the inner classes that are defined inside a block. Generally, this block is a method body. Sometimes this block can be a for loop or an if clause. Local Inner classes are not a member of any enclosing classes.

What is outer class and inner class?

Java inner class is defined inside the body of another class. Java inner class can be declared private, public, protected, or with default access whereas an outer class can have only public or default access. Java Nested classes are divided into two types.


2 Answers

By the language definition, the outer-class method is not visible in the inner class because it is shadowed.

Shadowing is based on name rather than signature. This is a good thing.

Consider the alternative. You could hide a subset of method overloads. Someone else could try to change the arguments in a call, to call one of the other overloaded methods. Simply changing the arguments could cause the recipient object to change. This would be surprising, and could cost time to debug.

From the Java Language Specification, 6.3.1:

Some declarations may be shadowed in part of their scope by another declaration of the same name, in which case a simple name cannot be used to refer to the declared entity. A declaration d of a type named n shadows the declarations of any other types named n that are in scope at the point where d occurs throughout the scope of d.

...

A declaration d is said to be visible at point p in a program if the scope of d includes p, and d is not shadowed by any other declaration at p. When the program point we are discussing is clear from context, we will often simply say that a declaration is visible.

like image 188
Andy Thomas Avatar answered Oct 13 '22 14:10

Andy Thomas


This will work :

public class Example {
    public void doSomething(final int a, final int b) {
    }

    public class Request {
        public int a;
        public int b;

        public void foo() {
            doSomething(a, b); // Error. Fix: Example.this.doSomething(a,b);
        }
    }
}

You have a namespace collision on the function name doSomething, hence the need to qualify.

like image 22
Amir Afghani Avatar answered Oct 13 '22 14:10

Amir Afghani