我知道如何使这段代码工作,但我很好奇为什么编译器无法弄清楚调用是否属于外部类方法:
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);
}
}
}
是否有更深层次的设计理由,而不是保护编码员犯错误?
答案 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)
默认情况下,内部类不会从相应的外部类继承。