pop*_*lop 4 java compilation ambiguity
我一直在努力理解java编译,我遇到了一个问题.假设我们有这样的课程设置
public class Ambiguity
{
static class G
{
void A()
{
System.out.println("Regular Method");
}
}
static class b
{
static void A()
{
System.out.println("Static Method");
}
}
public static void main(String[] args)
{
G b = new G();
b.A();
}
}
Run Code Online (Sandbox Code Playgroud)
编译器如何知道static void A()在类型对象上调用方法class b或常规方法的天气.基于我运行的测试它似乎调用对象(类型)方法但我不知道这是否始终是标准过程.在这种情况下,如何调用静态方法.void A()bGbG
b类型的和G,b的任何地方,其中变量b是在范围上.b因此不调用该类型的方法.由于本地范围变量更具体,因此会出现模糊现象.模糊的规则很复杂,但在JLS§6.4.2中进行了总结:
一个简单的名称可能出现在上下文中,它可能被解释为变量,类型或包的名称.在这些情况下,§6.5的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包.因此,有时可能无法通过其简单名称引用可见类型或包声明.我们说这样的声明是模糊的.
这样的模糊是不好的做法,应该避免.但是,在这种情况下,您可以通过为类型提供限定名称(第6.2节)来解决模糊问题.这会更改§6.5中适用的名称选择规则:
G b = new G();
Ambiguity.b.A(); // calls Ambiguity.b.A()
b.A(); // calls Ambiguity.G.A() on variable b
Run Code Online (Sandbox Code Playgroud)
打印:
Static Method Regular Method
~~~~
具体而言,b此上下文中的非限定名称最初被分类为不明确名称(第6.5.1节).然后根据§6.5.2中的优先级规则对其进行重新分类(粗体是我的突出显示,斜体是我的补充):
如果AmbiguousName是一个简单的名称,由一个标识符组成
•如果标识符出现的范围内(§6.3)的局部变量的声明(§14.4)或参数声明(§8.4.1,§8.8.1,§14.20)或字段声明(§8.3)具有该名称,然后AmbiguousName被重新分类为ExpressionName(...而不是TypeName,来自较低优先级规则3).