开发者

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

开发者 https://www.devze.com 2023-04-09 03:28 出处:网络
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:

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?


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.


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.


Inner classes do not by default inherit from their corresponding outer class.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号