2016-11-25 3 views
8

ich JLS 8 and in Chapter 6 gerade lese geschrieben:Einfach Name und qualifizierter Name

Ein qualifizierter Name Nx verwendet werden, um ein Mitglied eines Paket oder Referenztyp zu beziehen, wobei N ein einfacher oder qualifizierter Name ist und x ist eine Kennung. Wenn N ein Paket benennt, ist x ein Mitglied dieses Pakets, , das entweder ein Klassen- oder Schnittstellentyp oder ein Unterpaket ist. Wenn N-Namen ein Referenztyp oder eine Variable eines Referenztyps ist, dann benennt x einen Member dieses Typs, der entweder eine Klasse, eine Schnittstelle, ein Feld, oder eine Methode ist.

Ich konnte so vorstellen, dass dies mit:

class C 
{ 
    public int n; 
} 

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

j ein einfacher Name ist während c.n ein qualifizierter Name ist.

Jedoch in 6.2 Dinge werden kompliziert. Gegeben diesen Code:

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

und nach gesagt:

Das Auftreten von Länge in args.length ein Name ist, weil args.length ein qualifizierter Name ist (§6.5.6.2) und kein Feldzugangsausdruck (§15.11). Ein Feldzugriffsausdruck sowie ein Methodenaufruf Ausdruck, ein Methodenreferenzausdruck und eine qualifizierte Klasse Instanzerstellungsausdruck verwenden einen Bezeichner anstelle eines Namens bezeichnen das Mitglied von Interesse. Das Auftreten von length in args [0] .length() ist also kein Name, sondern ein Bezeichner, der in einen Methodenaufrufausdruck erscheint.

so denke ich, ich verstehe, dass nicht alles Ausdrücke qualifizierte Namen sind und sogar mein Ausdruck c.n

Ehrlich gesagt kann ich nicht die Unterscheidung jemand mir helfen, verstehen?

+0

Es wäre einfacher, die Abschnitte der Spezifikation zu lesen, auf die Sie sich beziehen, wenn Sie einige Links hinzufügen würden. –

+0

Was versuchen Sie hier zu verstehen? Versteht mich nicht falsch, ich werde die Frage nicht anklopfen, ich liebe es, JLS zu lesen, um solche Dinge zu finden, aber ich muss sagen, ich kämpfe auch mit der Unterscheidung - und ich denke, es könnte helfen, das zu verstehen spezifischer Kontext des vorliegenden Problems statt der Allgemeinheit der Spezifikation. –

Antwort

5

In Ihrem exemple:

int j; sind ein einfacher Ausdruck Namen, weil er aus einem einzigen Identifier besteht

Für qualifiziertes Beispiel aus den JLS 6.5.6.2. Qualified Expression Names:

Wenn ein Ausdruck Name der ist Q.Id, dann wurde Q bereits als Paketname, Typname oder Ausdrucksname klassifiziert.

In c.n, c ist ein Ausdruck Name, n ist ein Feld der Klasse T (Klasse C in Ihrem Beispiel). Also c.n ist ein qualifizierter Ausdruck Name.

args.length ist auch ein qualifizierter Ausdruck Name. args ist ein Array, also ist es nicht wirklich eine bestimmte Klasse (nein.Klassendatei aber run-time type signature is generated though), aber es ist immer noch ein Objekt mit einem Feld mit dem Namen length.

args[0].length() ist kein qualifizierter Name, da length() kein Mitglied der Klasse ist. Es ist ein Bezeichner eines Methodenaufrufausdrucks.

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} 

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

+0

Frage OP nicht nach dem 'args.length', sondern nach dem' args [0] .length() 'case, obwohl? –

+0

@AndyTurner In der Frage, die OP zitiert den Satz von der JLS sagen, dass args.length ein qualifizierter Name ist. Ich denke, es war klar, aber ich werde das auch die Antwort hinzufügen :) –

Verwandte Themen