具有方法名称和与外部类不同的签名的内部类

Tho*_*ews 9 java inner-classes

我知道如何使这个代码工作,但我很好奇为什么编译器无法弄清楚调用是外部类方法:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有更深层次的设计理由,而不是保护编码员犯错误?

And*_*mas 8

通过语言定义,外部类方法在内部类中是不可见的,因为它是阴影的.

阴影基于名称而非签名.这是一个很好的事情.

考虑替代方案.您可以隐藏方法重载的子集.其他人可能会尝试更改调用中的参数,以调用其他重载方法之一.简单地更改参数可能会导致收件人对象发生更改.这将是令人惊讶的,并且可能花费时间进行调试.

从Java语言规范,6.3.1:

某些声明可能会在其作用域的一部分中被另一个同名声明所遮蔽,在这种情况下,简单名称不能用于引用声明的实体.名为n的类型的声明d会影响名称为n的任何其他类型的声明,这些声明在整个d范围内出现d的范围内.

...

如果d的范围包括p,并且d不被p处的任何其他声明遮蔽,则声明d在程序中的点p处可见.当我们讨论的程序点从上下文中清楚时,我们通常只会说声明是可见的.