Source: http://4e00.com/java/java-language-specification-v2/expressions.doc.html
Timestamp: 2019-04-19 13:08:24+00:00

Document:
Much of the work in a program is done by evaluating expressions, either for their side effects, such as assignments to variables, or for their values, which can be used as arguments or operands in larger expressions, or to affect the execution sequence in statements, or both.
This chapter specifies the meanings of expressions and the rules for their evaluation.
An expression denotes nothing if and only if it is a method invocation (§15.12) that invokes a method that does not return a value, that is, a method declared void (§8.4). Such an expression can be used only as an expression statement (§14.8), because every other context in which an expression can appear requires the expression to denote something. An expression statement that is a method invocation may also invoke a method that produces a result; in this case the value returned by the method is quietly discarded.
Value set conversion (§5.1.8) is applied to the result of every expression that produces a value.
If the value of a variable of type float or double is used in this manner, then value set conversion (§5.1.8) is applied to the value of the variable.
The value of an expression is always assignment compatible (§5.2) with the type of the expression, just as the value stored in a variable is always compatible with the type of the variable.
If the type of an expression is float or double, then there is a question as to what value set (§4.2.3) the value of the expression is drawn from. This is governed by the rules of value set conversion (§5.1.8); these rules in turn depend on whether or not the expression is FP-strict.
Every compile-time constant expression (§15.28) is FP-strict. If an expression is not a compile-time constant expression, then consider all the class declarations, interface declarations, and method declarations that contain the expression. If any such declaration bears the strictfp modifier, then the expression is FP-strict.
If a class, interface, or method, X, is declared strictfp, then X and any class, interface, method, constructor, instance initializer, static initializer or variable initializer within X is said to be FP-strict.
The instanceof operator (§15.20.2). An expression whose type is a reference type may be tested using instanceof to find out whether the class of the object referenced by the run-time value of the expression is assignment compatible (§5.2) with some other reference type.
Casting (§5.5, §15.16). The class of the object referenced by the run-time value of the operand expression might not be compatible with the type specified by the cast. For reference types, this may require a run-time check that throws an exception if the class of the referenced object, as determined at run time, is not assignment compatible (§5.2) with the target type.
Assignment to an array component of reference type (§10.10, §15.13, §15.26.1). The type-checking rules allow the array type S to be treated as a subtype of T if S is a subtype of T, but this requires a run-time check for assignment to an array component, similar to the check performed for a cast.
Exception handling (§14.19). An exception is caught by a catch clause only if the class of the thrown exception object is an instanceof the type of the formal parameter of the catch clause.
In a cast, when the actual class of the object referenced by the value of the operand expression is not compatible with the target type specified by the cast operator (§5.5, §15.16); in this case a ClassCastException is thrown.
In an assignment to an array component of reference type, when the actual class of the object referenced by the value to be assigned is not compatible with the actual run-time component type of the array (§10.10, §15.13, §15.26.1); in this case an ArrayStoreException is thrown.
When an exception is not caught by any catch handler (§11.3); in this case the thread of control that encountered the exception first invokes the method uncaughtException for its thread group and then terminates.
A class instance creation expression (§15.9), array creation expression (§15.10), or string concatenation operatior expression (§15.18.1) throws an OutOfMemoryError if there is insufficient memory available.
An array creation expression throws a NegativeArraySizeException if the value of any dimension expression is less than zero (§15.10).
A field access (§15.11) throws a NullPointerException if the value of the object reference expression is null.
A method invocation expression (§15.12) that invokes an instance method throws a NullPointerException if the target reference is null.
An array access (§15.13) throws a NullPointerException if the value of the array reference expression is null.
An array access (§15.13) throws an ArrayIndexOutOfBoundsException if the value of the array index expression is negative or greater than or equal to the length of the array.
A cast (§15.16) throws a ClassCastException if a cast is found to be impermissible at run time.
An integer division (§15.17.2) or integer remainder (§15.17.3) operator throws an ArithmeticException if the value of the right-hand operand expression is zero.
An assignment to an array component of reference type (§15.26.1) throws an ArrayStoreException when the value to be assigned is not compatible with the component type of the array.
That is, the left-hand operand forgetIt() of the operator / throws an exception before the right-hand operand is evaluated and its embedded assignment of 2 to j occurs.
The Java programming language also guarantees that every operand of an operator (except the conditional operators &&, ||, and ? :) appears to be fully evaluated before any part of the operation itself is performed.
If the binary operator is an integer division / (§15.17.2) or integer remainder % (§15.17.3), then its execution may raise an ArithmeticException, but this exception is thrown only after both operands of the binary operator have been evaluated and only if these evaluations completed normally.
Java programming language implementations must respect the order of evaluation as indicated explicitly by parentheses and implicitly by operator precedence. An implementation may not take advantage of algebraic identities such as the associative law to rewrite expressions into a more convenient computational order unless it can be proven that the replacement expression is equivalent in value and in its observable side effects, even in the presence of multiple threads of execution (using the thread execution model in §17), for all possible computational values that might be involved.
In the case of floating-point calculations, this rule applies also for infinity and not-a-number (NaN) values. For example, !(x<y) may not be rewritten as x>=y, because these expressions have different values if either x or y is NaN or both are NaN.
Specifically, floating-point calculations that appear to be mathematically associative are unlikely to be computationally associative. Such computations must not be naively reordered.
For example, it is not correct for a Java compiler to rewrite 4.0*x*0.5 as 2.0*x; while roundoff happens not to be an issue here, there are large values of x for which the first expression produces infinity (because of overflow) but the second expression produces a finite result.
In contrast, integer addition and multiplication are provably associative in the Java programming language.
For example a+b+c, where a, b, and c are local variables (this simplifying assumption avoids issues involving multiple threads and volatile variables), will always produce the same answer whether evaluated as (a+b)+c or a+(b+c); if the expression b+c occurs nearby in the code, a smart compiler may be able to use this common subexpression.
Primary expressions include most of the simplest kinds of expressions, from which all others are constructed: literals, class literals, field accesses, method invocations, and array accesses. A parenthesized expression is also treated syntactically as a primary expression.
The type of a floating-point literal that ends with F or f is float and its value must be an element of the float value set (§4.2.3). The type of any other floating-point literal is double and its value must be an element of the double value set.
Evaluation of a lexical literal always completes normally.
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
The keyword this may be used only in the body of an instance method, instance initializer 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 (§15.12), 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.
The keyword this is also used in a special explicit constructor invocation statement, which can appear at the beginning of a constructor body (§8.8.5).
Any lexically enclosing instance can be referred to by explicitly qualifying the keyword this.
Let C be the class denoted by ClassName. Let n be an integer such that C is the nth lexically enclosing class of the class in which the qualified this expression appears. The value of an expression of the form ClassName.this is the nth lexically enclosing instance of this (§8.1.2). The type of the expression is C. It is a compile-time error if the current class is not an inner class of class C or C itself.
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. If the contained expression denotes a variable then the parenthesized expression also denotes that variable.
Parentheses do not affect in any way the choice of value set (§4.2.3) for the value of an expression of type float or double.
Unqualified class instance creation expressions begin with the keyword new. An unqualified class instance creation expression may be used to create an instance of a class, regardless of whether the class is a top-level (§7.6), member (§8.5, §9.5), local (§14.3) or anonymous class (§15.9.5).
Qualified class instance creation expressions begin with a Primary. A qualified class instance creation expression enables the creation of instances of inner member classes and their anonymous subclasses.
Both unqualified and qualified class instance creation expressions may optionally end with a class body. Such a class instance creation expression declares an anonymous class (§15.9.5) and creates an instance of it.
We say that a class is instantiated when an instance of the class is created by a class instance creation expression. Class instantiation involves determining what class is to be instantiated, what the enclosing instances (if any) of the newly created instance are, what constructor should be invoked to create the new instance and what arguments should be passed to that constructor.
If the class instance creation expression is an unqualified class instance creation expression, then let T be the ClassOrInterfaceType after the new token. It is a compile-time error if the class or interface named by T is not accessible (§6.6). If T is the name of a class, then an anonymous direct subclass of the class named by T is declared. It is a compile-time error if the class named by T is a final class. If T is the name of an interface then an anonymous direct subclass of Object that implements the interface named by T is declared. In either case, the body of the subclass is the ClassBody given in the class instance creation expression. The class being instantiated is the anonymous subclass.
Otherwise, the class instance creation expression is a qualified class instance creation expression. Let T be the name of the Identifier after the new token. It is a compile-time error if T is not the simple name (§6.2) of an accessible (§6.6) non-final inner class (§8.1.2) that is a member of the compile-time type of the Primary. It is also a compile-time error if T is ambiguous (§8.5). An anonymous direct subclass of the class named by T is declared. The body of the subclass is the ClassBody given in the class instance creation expression. The class being instantiated is the anonymous subclass.
If the class instance creation expression is an unqualified class instance creation expression, then the ClassOrInterfaceType must name a class that is accessible (§6.6) and not abstract, or a compile-time error occurs. In this case, the class being instantiated is the class denoted by ClassOrInterfaceType.
Otherwise, the class instance creation expression is a qualified class instance creation expression. It is a compile-time error if Identifier is not the simple name (§6.2) of an accessible (§6.6) non-abstract inner class (§8.1.2) T that is a member of the compile-time type of the Primary. It is also a compile-time error if Identifier is ambiguous (§8.5). The class being instantiated is the class denoted by Identifier.
The type of the class instance creation expression is the class type being instantiated.
If the class instance creation expression occurs in a static context (§8.1.2), then i has no immediately enclosing instance.
Otherwise, the immediately enclosing instance of i is this.
If C occurs in a static context, then i has no immediately enclosing instance.
Otherwise, if the class instance creation expression occurs in a static context, then a compile-time error occurs.
Otherwise, the immediately enclosing instance of i is the nth lexically enclosing instance of this (§8.1.2).
Otherwise, C is an inner member class (§8.5).
If the class instance creation expression occurs in a static context, then a compile-time error occurs.
Otherwise, if C is a member of an enclosing class then let O be the innermost lexically enclosing class of which C is a member, and let n be an integer such that O is the nth lexically enclosing class of the class in which the class instance creation expression appears. The immediately enclosing instance of i is the nth lexically enclosing instance of this.
Otherwise, a compile-time error occurs.
Otherwise, the class instance creation expression is a qualified class instance creation expression. The immediately enclosing instance of i is the object that is the value of the Primary expression.
If S occurs within a static context, then i has no immediately enclosing instance with respect to S.
Otherwise, the immediately enclosing instance of i with respect to S is the nth lexically enclosing instance of this.
Otherwise, S is an inner member class (§8.5).
Otherwise, if S is a member of an enclosing class then let O be the innermost lexically enclosing class of which S is a member, and let n be an integer such that O is the nth lexically enclosing class of the class in which the class instance creation expression appears. The immediately enclosing instance of i with respect to S is the nth lexically enclosing instance of this.
Otherwise, the class instance creation expression is a qualified class instance creation expression. The immediately enclosing instance of i with respect to S is the object that is the value of the Primary expression.
First, the actual arguments to the constructor invocation are determined.
If the S is a local class and S occurs in a static context, then the arguments in the argument list, if any, are the arguments to the constructor, in the order they appear in the expression.
Otherwise, the immediately enclosing instance of i with respect to S is the first argument to the constructor, followed by the arguments in the argument list of the class instance creation expression, if any, in the order they appear in the expression.
Otherwise the arguments in the argument list, if any, are the arguments to the constructor, in the order they appear in the expression.
Once the actual arguments have been determined, they are used to select a constructor of C, using the same rules as for method invocations (§15.12). As in method invocations, a compile-time method matching error results if there is no unique most-specific constructor that is both applicable and accessible.
Note that the type of the class instance creation expression may be an anonymous class type, in which case the constructor being invoked is an anonymous constructor.
First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.
Next, space is allocated for the new class instance. If there is insufficient space to allocate the object, evaluation of the class instance creation expression completes abruptly by throwing an OutOfMemoryError (§15.9.6).
The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.5.5).
Next, the actual arguments to the constructor are evaluated, left-to-right. If any of the argument evaluations completes abruptly, any argument expressions to its right are not evaluated, and the class instance creation expression completes abruptly for the same reason.
Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type. This process can be directed by explicit constructor invocation statements (§8.8) and is described in detail in §12.5.
An anonymous class declaration is automatically derived from a class instance creation expression by the compiler.
An anonymous class is never abstract (§8.1.1.1). An anonymous class is always an inner class (§8.1.2); it is never static (§8.1.1, §8.5.2). An anonymous class is always implicitly final (§8.1.1.2).
If S is not an inner class, or if S is a local class that occurs in a static context, then the anonymous constructor has one formal parameter for each actual argument to the class instance creation expression in which C is declared. The actual arguments to the class instance creation expression are used to determine a constructor cs of S, using the same rules as for method invocations (§15.12). The type of each formal parameter of the anonymous constructor must be identical to the corresponding formal parameter of cs. The body of the constructor consists of an explicit constructor invocation (§8.8.5.1) of the form super(...), where the actual arguments are the formal parameters of the constructor, in the order they were declared.
Otherwise, the first formal parameter of the constructor of C represents the value of the immediately enclosing instance of i with respect to S. The type of this parameter is the class type that immediately encloses the declaration of S. The constructor has an additional formal parameter for each actual argument to the class instance creation expression that declared the anonymous class. The nth formal parameter e corresponds to the n - 1st actual argument. The actual arguments to the class instance creation expression are used to determine a constructor cs of S, using the same rules as for method invocations (§15.12). The type of each formal parameter of the anonymous constructor must be identical to the corresponding formal parameter of cs. The body of the constructor consists of an explicit constructor invocation (§8.8.5.1) of the form o.super(...), where o is the first formal parameter of the constructor, and the actual arguments are the subsequent formal parameters of the constructor, in the order they were declared.
In all cases, the throws clause of an anonymous constructor must list all the checked exceptions thrown by the explicit superclass constructor invocation statement contained within the anonymous constructor, and all checked exceptions thrown by any instance initializers or instance variable initializers of the anonymous class.
Note that it is possible for the signature of the anonymous constructor to refer to an inaccessible type (for example, if such a type occurred in the signature of the superclass constructor cs). This does not, in itself, cause any errors at either compile time or run time.
Compare this to the treatment of array creation expressions (§15.10), for which the out-of-memory condition is detected after evaluation of the dimension expressions (§15.10.3).
An array creation expression creates an object that is a new array whose elements are of the type specified by the PrimitiveType or TypeName. The TypeName may name any named reference type, even an abstract class type (§8.1.1.1) or an interface type (§9).
The type of the creation expression is an array type that can denoted by a copy of the creation expression from which the new keyword and every DimExpr expression and array initializer have been deleted.
The type of each dimension expression within a DimExpr must be an integral type, or a compile-time error occurs. Each expression undergoes unary numeric promotion (§5.6.1). The promoted type must be int, or a compile-time error occurs; this means, specifically, that the type of a dimension expression must not be long.
If an array initializer is provided, the newly allocated array will be initialized with the values provided by the array initializer as described in §10.6.
Then, if a single DimExpr appears, a single-dimensional array is created of the specified length, and each component of the array is initialized to its default value (§4.5.5).
If an array creation expression contains N DimExpr expressions, then it effectively executes a set of nested loops of depth N - 1 to create the implied arrays of arrays.
A multidimensional array need not have arrays of the same length at each level.
In an array creation expression (§15.10), there may be one or more dimension expressions, each within brackets. Each dimension expression is fully evaluated before any part of any dimension expression to its right.
because the out-of-memory condition is detected after the dimension expression oldlen = len is evaluated.
Compare this to class instance creation expressions (§15.9), which detect the out-of-memory condition before evaluating argument expressions (§15.9.6).
The special forms using the keyword super are valid only in an instance method, instance initializer or constructor, or in the initializer of an instance variable of a class; these are exactly the same situations in which the keyword this may be used (§15.8.3). The forms involving super may not be used anywhere in the class Object, since Object has no superclass; if super appears in class Object, then a compile-time error results.
Suppose that a field access expression T.super.name appears within class C, and the immediate superclass of the class denoted by T is a class whose fully qualified name is S. Then T.super.name is treated exactly as if it had been the expression ((S)T.this).name.
Thus the expression T.super.name can access the field named name that is visible in the class named by S, even if that field is hidden by a declaration of a field named name in the class named by T.
It is a compile-time error if the class denoted by T is not a lexically enclosing class of the current class.
Determining the method that will be invoked by a method invocation expression involves several steps. The following three sections describe the compile-time processing of a method invocation; the determination of the type of the method invocation expression is described in §15.12.3.
If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier. If the Identifier appears within the scope (§6.3) of a visible method declaration with that name, then there must be an enclosing type declaration of which that method is a member. Let T be the innermost such type declaration. The class or interface to search is T.
T is the class Object.
The class or interface determined by the process described in §15.12.1 is searched for all method declarations applicable to this method invocation; method definitions inherited from superclasses and superinterfaces are included in this search.
Whether a method declaration is accessible (§6.6) at a method invocation depends on the access modifier (public, none, protected, or private) in the method declaration and on where the method invocation appears.
If more than one method declaration is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
If there is exactly one maximally specific method, then it is in fact the most specific method; it is necessarily more specific than any other method that is applicable and accessible. It is then subjected to some further compile-time checks as described in §15.12.3.
Here the most specific declaration of method test is the one taking a parameter of type ColoredPoint. Because the result type of the method is int, a compile-time error occurs because an int cannot be converted to a String by assignment conversion. This example shows that the result types of methods do not participate in resolving overloaded methods, so that the second test method, which returns a String, is not chosen, even though it has a result type that would allow the example program to compile without error.
The most applicable method is chosen at compile time; its descriptor determines what method is actually executed at run time. If a new method is added to a class, then source code that was compiled with the old definition of the class might not use the new method, even if a recompilation would cause this method to be chosen.
Ideally, source code should be recompiled whenever code that it depends on is changed. However, in an environment where different classes are maintained by different organizations, this is not always feasible. Defensive programming with careful attention to the problems of class evolution can make upgraded code much more robust. See §13 for a detailed discussion of binary compatibility and type evolution.
The qualifying type of the method invocation (§13.1).
Otherwise, if the part of the method invocation before the left parenthesis is of the form super . Identifier or of the form ClassName.super.Identifier then the invocation mode is super.
Otherwise, let T be the enclosing type declaration of which the method is a member, and let n be an integer such that T is the nth lexically enclosing type declaration (§8.1.2) of the class whose declaration immediately contains the method invocation. Then the target reference is the nth lexically enclosing instance (§8.1.2) of this. It is a compile-time error if the nth lexically enclosing instance (§8.1.2) of this does not exist.
If the fourth production for MethodInvocation, ClassName.super, is involved, then the target reference is the value of ClassName.this.
Let C be the class containing the method invocation, and let T be the qualifying type of the method invocation (§13.1), and m be the name of the method, as determined at compile time (§15.12.3). An implementation of the Java programming language must insure, as part of linkage, that the method m still exists in the type T. If this is not true, then a NoSuchMethodError (which is a subclass of IncompatibleClassChangeError) occurs. If the invocation mode is interface, then the implementation must also check that the target reference type still implements the specified interface. If the target reference type does not still implement the interface, then an IncompatibleClassChangeError occurs.
If T is in a different package than C, and T is protected, then T is accessible if and only if C is a subclass of T.
If m is private, then m is accessible if and only if C is T, or C encloses T, or T encloses C, or T and C are both enclosed by a third class.
If the invocation mode is super, then S is initially the qualifying type (§13.1) of the method invocation.
Let X be the compile-time type of the target reference of the method invocation.
If the invocation mode is super or interface, then this is the method to be invoked, and the procedure terminates.
If the invocation mode is virtual, and the declaration in S overrides (§8.4.6.1) X.m, then the method declared in S is the method to be invoked, and the procedure terminates.
Otherwise, if S has a superclass, this same lookup procedure is performed recursively using the direct superclass of S in place of S; the method to be invoked is the result of the recursive invocation of this lookup procedure.
The above procedure will always find a non-abstract, accessible method to invoke, provided that all classes and interfaces in the program have been consistently compiled. However, if this is not the case, then various errors may occur. The specification of the behavior of a Java virtual machine under these circumstances is given by The Java Virtual Machine Specification, Second Edition.
The newly created activation frame becomes the current activation frame. The effect of this is to assign the argument values to corresponding freshly created parameter variables of the method, and to make the target reference available as this, if there is a target reference. Before each argument value is assigned to its corresponding parameter variable, it is subjected to method invocation conversion (§5.3), which includes any required value set conversion (§5.1.8).
If the method m is a native method but the necessary native, implementation-dependent binary code has not been loaded or otherwise cannot be dynamically linked, then an UnsatisfiedLinkError is thrown.
If the method m is synchronized, then an object must be locked before the transfer of control. No further progress can be made until the current thread can obtain the lock. If there is a target reference, then the target must be locked; otherwise the Class object for class S, the class of the method m, must be locked. Control is then transferred to the body of the method m to be invoked. The object is automatically unlocked when execution of the body of the method has completed, whether normally or abruptly. The locking and unlocking behavior is exactly as if the body of the method were embedded in a synchronized statement (§14.18).
As part of an instance method invocation (§15.12), there is an expression that denotes the object to be invoked. This expression appears to be fully evaluated before any part of any argument expression to the method invocation is evaluated.
the occurrence of s before ".startsWith" is evaluated first, before the argument expression s="two". Therefore, a reference to the string "one" is remembered as the target reference before the local variable s is changed to refer to the string "two". As a result, the startsWith method is invoked for target object "one" with argument "two", so the result of the invocation is false, as the string "one" does not start with "two". It follows that the test program does not print "oops".
Overriding is sometimes called "late-bound self-reference"; in this example it means that the reference to clear in the body of Point.move (which is really syntactic shorthand for this.clear) invokes a method chosen "late" (at run time, based on the run-time class of the object referenced by this) rather than a method chosen "early" (at compile time, based only on the type of this). This provides the programmer a powerful way of extending abstractions and is a key idea in object-oriented programming.
An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets). Note that the array reference expression may be a name or any primary expression that is not an array creation expression (§15.10).
Otherwise, the value of the array reference expression indeed refers to an array. If the value of the index expression is less than zero, or greater than or equal to the array's length, then an ArrayIndexOutOfBoundsException is thrown.
Postfix expressions include uses of the postfix ++ and -- operators. Also, as discussed in §15.8, names are not considered to be primary expressions, but are handled separately in the grammar to avoid certain ambiguities. They become interchangeable only here, at the level of precedence of postfix expressions.
Note that the binary numeric promotion mentioned above may include value set conversion (§5.1.8). If necessary, value set conversion is applied to the sum prior to its being stored in the variable.
Note that the binary numeric promotion mentioned above may include value set conversion (§5.1.8). If necessary, value set conversion is applied to the difference prior to its being stored in the variable.
Note that the binary numeric promotion mentioned above may include value set conversion (§5.1.8). If necessary, format conversion is applied to the difference prior to its being stored in the variable.
Note that unary numeric promotion performs value set conversion (§5.1.8). Whatever value set the promoted operand value is drawn from, the unary negation operation is carried out and the result is drawn from that same value set. That result is then subject to further value set conversion.
At run time, the value of the unary minus expression is the arithmetic negation of the promoted value of the operand.
For integer values, negation is the same as subtraction from zero. The Java programming language 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.
A cast operator has no effect on the choice of value set (§4.2.3) for a value of type float or type double. Consequently, a cast to type float within an expression that is not FP-strict (§15.4) does not necessarily cause its value to be converted to an element of the float value set, and a cast to type double within an expression that is not FP-strict does not necessarily cause its value to be converted to an element of the double value set.
At run time, the operand value is converted by casting conversion (§5.5) to the type specified by the cast operator.
Not all casts are permitted by the language. Some casts result in an error at compile time. For example, a primitive value may not be cast to a reference type. Some casts can be proven, at compile time, always to be correct at run time. For example, it is always correct to convert a value of a class type to the type of its superclass; such a cast should require no special action at run time. Finally, some casts cannot be proven to be either always correct or always incorrect at compile time. Such casts require a test at run time.
A ClassCastException is thrown if a cast is found at run time to be impermissible.
Note that binary numeric promotion performs value set conversion (§5.1.8).
If the type of the multiplication expression is float, then the float value set must be chosen.
If the type of the multiplication expression is double, then the double value set must be chosen.
If the type of the multiplication expression is float, then either the float value set or the float-extended-exponent value set may be chosen, at the whim of the implementation.
If the type of the multiplication expression is double, then either the double value set or the double-extended-exponent value set may be chosen, at the whim of the implementation.
Next, a value must be chosen from the chosen value set to represent the product. If the magnitude of the product is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign. Otherwise, the product is rounded to the nearest value in the chosen value set using IEEE 754 round-to-nearest mode. The Java programming language requires support of gradual underflow as defined by IEEE 754 (§4.2.4).
If the type of the division expression is float, then the float value set must be chosen.
If the type of the division expression is double, then the double value set must be chosen.
If the type of the division expression is float, then either the float value set or the float-extended-exponent value set may be chosen, at the whim of the implementation.
If the type of the division expression is double, then either the double value set or the double-extended-exponent value set may be chosen, at the whim of the implementation.
Next, a value must be chosen from the chosen value set to represent the quotient. If the magnitude of the quotient is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign. Otherwise, the quotient is rounded to the nearest value in the chosen value set using IEEE 754 round-to-nearest mode. The Java programming language requires support of gradual underflow as defined by IEEE 754 (§4.2.4).
In C and C++, the remainder operator accepts only integral operands, but in the Java programming language, it also accepts floating-point operands.
The result of a floating-point remainder operation as computed by the % operator is not the same as that produced by the remainder operation defined by IEEE 754. The IEEE 754 remainder operation computes the remainder from a rounding division, not a truncating division, and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java programming language defines % on floating-point operations to behave in a manner analogous to that of the integer remainder operator; this may be compared with the C library function fmod. The IEEE 754 remainder operation may be computed by the library routine Math.IEEEremainder.
If T is boolean, then use new Boolean(x).
If T is char, then use new Character(x).
If T is byte, short, or int, then use new Integer(x).
If T is long, then use new Long(x).
If T is float, then use new Float(x).
If T is double, then use new Double(x).
Now only reference values need to be considered. If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l). Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.
The toString method is defined by the primordial class Object; many classes override it, notably Boolean, Character, Integer, Long, Float, Double, and String.
If the type of the addition expression is float, then the float value set must be chosen.
If the type of the addition expression is double, then the double value set must be chosen.
If the type of the addition expression is float, then either the float value set or the float-extended-exponent value set may be chosen, at the whim of the implementation.
If the type of the addition expression is double, then either the double value set or the double-extended-exponent value set may be chosen, at the whim of the implementation.
Next, a value must be chosen from the chosen value set to represent the sum. If the magnitude of the sum is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign. Otherwise, the sum is rounded to the nearest value in the chosen value set using IEEE 754 round-to-nearest mode. The Java programming language requires support of gradual underflow as defined by IEEE 754 (§4.2.4).
The binary - operator performs subtraction when applied to two operands of numeric type producing the difference of its operands; the left-hand operand is the minuend and the right-hand operand is the subtrahend. For both integer and floating-point subtraction, it is always the case that a-b produces the same result as a+(-b).
Note that, for integer values, subtraction from zero is the same as negation. However, for floating-point operands, subtraction from zero is not the same as negation, because if x is +0.0, then 0.0-x is +0.0, but -x is -0.0.
The shift operators include left shift <<, signed right shift >>, and unsigned right shift >>>; they are syntactically left-associative (they group left-to-right). The left-hand operand of a shift operator is the value to be shifted; the right-hand operand specifies the shift distance.
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.
If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f. The shift distance actually used is therefore always in the range 0 to 63, inclusive.
The relational operators are syntactically left-associative (they group left-to-right), but this fact is not useful; for example, a<b<c parses as (a<b)<c, which is always a compile-time error, because the type of a<b is always boolean and < is not an operator on boolean values.
Note that binary numeric promotion performs value set conversion (§5.1.8). Comparison is carried out accurately on floating-point values, no matter what value sets their representing values were drawn from.
At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast (§15.16) to the ReferenceType without raising a ClassCastException. Otherwise the result is false.
The result of != is false if the operands are both true or both false; otherwise, the result is true. Thus != behaves the same as ^ (§15.22.2) when applied to boolean operands.
A compile-time error occurs if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.
While == may be used to compare references of type String, such an equality test determines whether or not the two operands refer to the same String object. The result is false if the operands are distinct String objects, even if they contain the same sequence of characters. The contents of two strings s and t can be tested for equality by the method invocation s.equals(t). See also §3.10.5.
The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. It is syntactically left-associative (it groups left-to-right). It is fully associative with respect to both side effects and result value; that is, for any expressions a, b, and c, evaluation of the expression ((a)&&(b))&&(c) produces the same result, with the same side effects occurring in the same order, as evaluation of the expression (a)&&((b)&&(c)).
The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. It is syntactically left-associative (it groups left-to-right). It is fully associative with respect to both side effects and result value; that is, for any expressions a, b, and c, evaluation of the expression ((a)||(b))||(c) produces the same result, with the same side effects occurring in the same order, as evaluation of the expression (a)||((b)||(c)).
At run time, the left-hand operand expression is evaluated first; if its value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated and its value becomes the value of the conditional-or expression.
Thus, || computes the same result as | on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.
Note that it is not permitted for either the second or the third operand expression to be an invocation of a void method. In fact, it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear (§14.8).
Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs value set conversion (§5.1.8).
The result of the first operand of an assignment operator must be a variable, or a compile-time error occurs. This operand may be a named variable, such as a local variable or a field of the current object or class, or it may be a computed variable, as can result from a field access (§15.11) or an array access (§15.13). The type of the assignment expression is the type of the variable.
A variable that is declared final cannot be assigned to (unless it is a blank final variable (§4.5.4)), because when an access of a final variable is used as an expression, the result is a value, not a variable, and so it cannot be used as the first operand of an assignment operator.
Otherwise, the value of the right-hand operand is converted to the type of the left-hand variable, is subjected to value set conversion (§5.1.8) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
Otherwise, the value of the array reference subexpression indeed refers to an array. If the value of the index subexpression is less than zero, or greater than or equal to the length of the array, then no assignment occurs and an ArrayIndexOutOfBoundsException is thrown.
If TC is a primitive type, then SC is necessarily the same as TC. The value of the right-hand operand is converted to the type of the selected array component, is subjected to value set conversion (§5.1.8) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the array component.
If TC is a reference type, then SC may not be the same as TC, but rather a type that extends or implements TC. Let RC be the class of the object referred to by the value of the right-hand operand at run time.
All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly (the only possibility is an integer division by zero-see §15.17.2), then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.8) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
The saved value of the array component and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly (the only possibility is an integer division by zero-see §15.17.2), then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the selected array component, subjected to value set conversion (§5.1.8) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the array component.
Unlike C and C++, the Java programming language has no comma operator.
Compile-time constant expressions are used in case labels in switch statements (§14.10) and have a special significance for assignment conversion (§5.2).
A compile-time constant expression is always treated as FP-strict (§15.4), even if it occurs in a context where a non-constant expression would not be considered to be FP-strict.

References: §15
 §15
 §15
 §15
 §15
 §15
 §17
 §9
 §12
 §8
 §10
 §15
 §15
 §15
 §13
 §15
 §3
 §15
 §15