CHAPTER 15: Expressions Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

15.14 Unary Operators

15.14.1 Prefix Increment Operator ++ , 15.14.2 Prefix Decrement Operator -- , 15.14.3 Unary Plus Operator + , 15.14.4 Unary Minus Operator - , 15.14.5 Bitwise Complement Operator ~ , 15.14.6 Logical Complement Operator !

The unary operators include + , - , ++ , -- , ~ , ! , and cast operators. Expressions with unary operators group right-to-left, so that -~x means the same as -(~x) .


UnaryExpression:

	PreIncrementExpression

	PreDecrementExpression

	+ UnaryExpression

	- UnaryExpression

	UnaryExpressionNotPlusMinus

PreIncrementExpression:

	++ UnaryExpression

PreDecrementExpression:

	-- UnaryExpression

UnaryExpressionNotPlusMinus:

	PostfixExpression

	~ UnaryExpression

	! UnaryExpression

	CastExpression

The following productions from S15.15 are repeated here for convenience:


CastExpression:

	( PrimitiveType ) UnaryExpression

	( ReferenceType ) UnaryExpressionNotPlusMinus

This portion of the Java grammar contains some tricks to avoid two potential syntactic ambiguities.

The first potential ambiguity would arise in expressions such as (p)+q , which looks, to a C or C++ programmer, as though it could be either be a cast to type p of a unary + operating on q , or a binary addition of two quantities p and q . In C and C++, the parser handles this problem by performing a limited amount of semantic analysis as it parses, so that it knows whether p is the name of a type or the name of a variable.

Java takes a different approach. The result of the + operator must be numeric, and all type names involved in casts on numeric values are known keywords. Thus, if p is a keyword naming a primitive type, then (p)+q can make sense only as a cast of a unary expression. However, if p is not a keyword naming a primitive type, then (p)+q can make sense only as a binary arithmetic operation. Similar remarks apply to the - operator. The grammar shown above splits CastExpression into two cases to make this distinction. The nonterminal UnaryExpression includes all unary operator, but the nonterminal UnaryExpressionNotPlusMinus excludes uses of all unary operators that could also be binary operators, which in Java are + and - .

The second potential ambiguity is that the expression (p)++ could, to a C or C++ programmer, appear to be either a postfix increment of a parenthesized expression or the beginning of a cast, for example, in (p)++q . As before, parsers for C and C++ know whether p is the name of a type or the name of a variable. But a parser using only one-token lookahead and no semantic analysis during the parse would not be able to tell, when ++ is the lookahead token, whether (p) should be considered a Primary expression or left alone for later consideration as part of a CastExpression.

In Java, the result of the ++ operator must be numeric, and all type names involved in casts on numeric values are known keywords. Thus, if p is a keyword naming a primitive type, then (p)++ can make sense only as a cast of a prefix increment expression, and there had better be an operand such as q following the ++ . However, if p is not a keyword naming a primitive type, then (p)++ can make sense only as a postfix increment of p . Similar remarks apply to the -- operator. The nonterminal UnaryExpressionNotPlusMinus therefore also excludes uses of the prefix operators ++ and -- .


15.14.1 Prefix Increment Operator ++

A unary expression preceded by a ++ operator is a prefix increment expression. The result of the unary expression must be a variable of a numeric type, or a compile-time error occurs. The type of the prefix increment expression is the type of the variable. The result of the prefix increment expression is not a variable, but a value.

At run time, if evaluation of the operand expression completes abruptly, then the prefix increment expression completes abruptly for the same reason and no incrementation occurs. Otherwise, the value 1 is added to the value of the variable and the sum is stored back into the variable. Before the addition, binary numeric promotion (S5.6.2) is performed on the value 1 and the value of the variable. If necessary, the sum is narrowed by a narrowing primitive conversion (S5.1.3) to the type of the variable before it is stored. The value of the prefix increment expression is the value of the variable after the new value is stored.

A variable that is declared final cannot be incremented, because when an access of a final variable is used as an expression, the result is a value, not a variable. Thus, it cannot be used as the operand of a prefix increment operator.


15.14.2 Prefix Decrement Operator --

A unary expression preceded by a -- operator is a prefix decrement expression. The result of the unary expression must be a variable of a numeric type, or a compile-time error occurs. The type of the prefix decrement expression is the type of the variable. The result of the prefix decrement expression is not a variable, but a value.

At run time, if evaluation of the operand expression completes abruptly, then the prefix decrement expression completes abruptly for the same reason and no decrementation occurs. Otherwise, the value 1 is subtracted from the value of the variable and the difference is stored back into the variable. Before the subtraction, binary numeric promotion (S5.6.2) is performed on the value 1 and the value of the variable. If necessary, the difference is narrowed by a narrowing primitive conversion (S5.1.3) to the type of the variable before it is stored. The value of the prefix decrement expression is the value of the variable after the new value is stored.

A variable that is declared final cannot be decremented, because when an access of a final variable is used as an expression, the result is a value, not a variable. Thus, it cannot be used as the operand of a prefix decrement operator.


15.14.3 Unary Plus Operator +

The type of the operand expression of the unary + operator must be a primitive numeric type, or a compile-time error occurs. Unary numeric promotion (S5.6.1) is performed on the operand. The type of the unary plus expression is the promoted type of the operand. The result of the unary plus expression is not a variable, but a value, even if the result of the operand expression is a variable.

At run time, the value of the unary plus expression is the promoted value of the operand.


15.14.4 Unary Minus Operator -

The type of the operand expression of the unary - operator must be a primitive numeric type, or a compile-time error occurs. Unary numeric promotion (S5.6.1) is performed on the operand. The type of the unary minus expression is the promoted type of the operand.

At run time, the value of the unary plus expression is the arithmetic negation of the promoted value of the operand.

For integer values, negation is the same as subtraction from zero. Java uses two's-complement representation for integers, and the range of two's-complement values is not symmetric, so negation of the maximum negative int or long results in that same maximum negative number. Overflow occurs in this case, but no exception is thrown. For all integer values x , -x equals (~x)+1 .

For floating-point values, negation is not the same as subtraction from zero, because if x is +0.0 , then 0.0-x equals +0.0 , but -x equals -0.0 . Unary minus merely inverts the sign of a floating-point number. Special cases of interest:


15.14.5 Bitwise Complement Operator ~

The type of the operand expression of the unary ~ operator must be a primitive integral type, or a compile-time error occurs. Unary numeric promotion (S5.6.1) is performed on the operand. The type of the unary bitwise complement expression is the promoted type of the operand.

At run time, the value of the unary bitwise complement expression is the bitwise complement of the promoted value of the operand; note that, in all cases, ~x equals (-x)-1 .


15.14.6 Logical Complement Operator !

The type of the operand expression of the unary ! operator must be boolean, or a compile-time error occurs. The type of the unary logical complement expression is boolean .

At run time, the value of the unary logical complement expression is true if the operand value is false and false if the operand value is true .

Top© 1996 Sun Microsystems, Inc. All rights reserved.