简单名称和限定名称

xde*_*000 8 java

我正在阅读JLS 8,在第6章中写道:

限定名称Nx可用于指代包或引用类型的成员,其中N是简单或限定名称,x是标识符.如果N命名一个包,则x是该包的成员,该包是类或接口类型或子包.如果N命名引用类型或引用类型的变量,则x命名该类型的成员,该类型是类,接口,字段或方法.

所以我可以想象这样:

class C
{
    public int n;
}

int j;
C c = new C(); 
j = 11;  
c.n = 11;
Run Code Online (Sandbox Code Playgroud)

j是一个简单的名称,c.n而是一个合格的名称.

然而在6.2中事情变得复杂.给出这段代码:

class Test { 
 public static void main(String[] args) { 
 Class c = System.out.getClass(); 
 System.out.println(c.toString().length() + 
 args[0].length() + args.length); 
 } 
}
Run Code Online (Sandbox Code Playgroud)

之后说:

args.length中长度的出现是一个名称,因为args.length是限定名称(第6.5.6.2节)而不是字段访问表达式(第15.11节).字段访问表达式以及方法调用表达式,方法引用表达式和限定类实例创建表达式使用标识符而不是名称来表示感兴趣的成员.因此,args [0] .length()中长度的出现不是名称,而是出现在方法调用表达式中的标识符.

所以我想我明白,并非所有表达都是合格的名字,甚至是我的表达 c.n

老实说,我无法理解任何人可以帮助我的区别?

ala*_*inm 5

在你的例子中:

int j; 是一个简单的表达式名称,因为它由一个标识符组成

对于合格的例子,来自JLS 6.5.6.2.合格的表达名称:

如果表达式名称的格式为Q.Id,则Q已被分类为包名称,类型名称或表达式名称.

c.n,c是表达式名称,n是类T的字段(在您的示例中为C类).所以c.n是一个合格的表达式名称.

args.length也是一个合格的表达式名称.args是一个数组,所以它不是一个特定的类(没有.class文件,但生成了运行时类型签名),但它仍然是一个名为字段的对象length.

args[0].length()不是限定名称,因为length()它不是该类的成员.它是方法调用表达式的标识符.

MethodInvocation:
  MethodName ( [ArgumentList] )
  TypeName . [TypeArguments] Identifier ( [ArgumentList] )
  ExpressionName . [TypeArguments] Identifier ( [ArgumentList] )
  Primary . [TypeArguments] Identifier ( [ArgumentList] )
  super . [TypeArguments] Identifier ( [ArgumentList] )
  TypeName . super . [TypeArguments] Identifier ( [ArgumentList] )

ArgumentList:
  Expression {, Expression}
Run Code Online (Sandbox Code Playgroud)

参看 https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12