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

时间:2011-09-29 16:35:51

标签: 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);
        }
    }
}

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

3 个答案:

答案 0 :(得分:8)

通过语言定义,外层类方法在内部类中不可见,因为它是 shadowed

阴影基于名称而非签名。这是的事情。

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

来自Java语言规范,6.3.1:

  

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

     

...

     

如果声明d在程序中的点p处可见,则说明   d的范围包括p,d不受任何其他声明的影响   在p。当我们讨论的程序点从上下文中清楚时,   我们通常会简单地说声明是可见的。

答案 1 :(得分:1)

这将有效:

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);
        }
    }
}

您在函数名doSomething上存在名称空间冲突,因此需要符合条件。

答案 2 :(得分:0)

默认情况下,内部类不会从相应的外部类继承。