简单名称和限定名称

时间:2016-11-25 13:17:38

标签: java

我正在阅读JLS 8 and in Chapter 6写道:

  

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

所以我可以想象有这个:

class C
{
    public int n;
}

int j;
C c = new C(); 
j = 11;  
c.n = 11;

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

之后说:

  

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

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

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

1 个答案:

答案 0 :(得分:5)

在你的例子中:

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

组成

有关限定示例,请从JLS 6.5.6.2. Qualified Expression Names

开始
  

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

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

args.length也是一个合格的表达式名称。 args是一个数组,所以它不是一个特定的类(没有.class文件而是run-time type signature is generated though)但它仍然是一个名为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}

比照。 https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12