我正在阅读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
老实说,我无法理解任何人可以帮助我的区别吗?
答案 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