CHAPTER 15: Expressions |
![]() Previous |
![]() Java Language |
![]() Index |
![]() Next |
Primary expressions include most of the simplest kinds of expressions, from which all others are constructed: literals, field accesses, method invocations, and array accesses. A parenthesized expression is also treated syntactically as a primary expression.
Primary: PrimaryNoNewArray ArrayCreationExpression PrimaryNoNewArray: Literal this ( Expression ) ClassInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess
As programming language grammars go, this part of the Java grammar is unusual, in two ways. First, one might expect simple names, such as names of local variables and method parameters, to be primary expressions. For technical reasons, names are lumped together with primary expressions a little later when postfix expressions are introduced (S15.13).
The technical reasons have to do with allowing left-to-right parsing of Java programs with only one-token lookahead. Consider the expressions (z[3]) and (z[]) . The first is a parenthesized array access (S15.12) and the second is the start of a cast (S15.15). At the point that the look-ahead symbol is [ , a left-to-right parse will have reduced the z to the nonterminal Name. In the context of a cast we prefer not to have to reduce the name to a Primary, but if Name were one of the alternatives for Primary, then we could not tell whether to do the reduction (that is, we could not determine whether the current situation would turn out to be a parenthesized array access or a cast) without looking ahead two tokens, to the token following the [ . The Java grammar presented here avoids the problem by keeping Name and Primary separate and allowing either in certain other syntax rules (those for MethodInvocation, ArrayAccess, PostfixExpression, but not for FieldAccess, because this is covered by Name). This strategy effectively defers the question of whether a Name should be treated as a Primary until more context can be examined. (Other problems remain with cast expressions; see S19.1.5.)
The second unusual feature avoids a potential grammatical ambiguity in the expression:
new int[3][3]
which in Java always means a single creation of a multidimensional array, but which, without appropriate grammatical finesse, might also be interpreted as meaning the same as:
(new int[3])[3]
This ambiguity is eliminated by splitting the expected definition of Primary into Primary and PrimaryNoNewArray. (This may be compared to the splitting of Statement into Statement and StatementNoShortIf (S14.4) to avoid the "dangling else " problem.)
A literal (S3.10) denotes a fixed, unchanging value.
The following production from S3.10 is repeated here for convenience:
Literal: IntegerLiteral FloatingPointLiteral BooleanLiteral CharacterLiteral StringLiteral NullLiteral
The type of a literal is determined as follows:
Evaluation of a literal always completes normally.
The keyword this may be used only in the body of an instance method or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
When used as a primary expression, the keyword this denotes a value, that is a reference to the object for which the instance method was invoked (S15.11), or to the object being constructed. The type of this is the class C within which the keyword this occurs. At run time, the class of the actual object referred to may be the class C or any subclass of C.
In the example:
class IntVector { int[] v; boolean equals(IntVector other) { if (this == other) return true; if (v.length != other.v.length) return false; for (int i = 0; i < v.length; i++) if (v[i] != other.v[i]) return false; return true; } }
the class IntVector implements a method equals , which compares two vectors. If the other vector is the same vector object as the one for which the equals method was invoked, then the check can skip the length and value comparisons. The equals method implements this check by comparing the reference to the other object to this .
The keyword this is also used in a special explicit constructor invocation statement, which can appear at the beginning of a constructor body (S8.6.5).
A parenthesized expression is a primary expression whose type is the type of the contained expression and whose value at run time is the value of the contained expression.
![]() | © 1996 Sun Microsystems, Inc. All rights reserved. |