📄 15.doc.html
字号:
<html>
<head>
<title>The Java Language Specification Expressions</title>
</head>
<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>
<a href="index.html">Contents</a> | <a href="14.doc.html">Prev</a> | <a href="16.doc.html">Next</a> | <a href="j.index.doc1.html">Index</a>
<hr><br>
<a name="4709"></a>
<p><strong>
CHAPTER 15 </strong></p>
<a name="44393"></a>
<h1>Expressions</h1>
<hr><p>
<a name="11757"></a>
Much of the work in a Java program is done by evaluating <i>expressions</i>, 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.
<p><a name="236101"></a>
This chapter specifies the meanings of Java expressions and the rules for their evaluation.<p>
<a name="228862"></a>
<h2>15.1 Evaluation, Denotation, and Result</h2>
<a name="228864"></a>
When an expression in a Java program is <i>evaluated</i> (<i>executed</i>), the <i>result</i> denotes
one of three things:
<p><ul><a name="228896"></a>
<li>A variable <a href="4.doc.html#18470">(§4.5)</a> (in C, this would be called an <i>lvalue</i>)
<a name="19788"></a>
<li>A value (<a href="4.doc.html#85587">§4.2</a>, <a href="4.doc.html#9317">§4.3</a>)
<a name="229505"></a>
<li>Nothing (the expression is said to be <code>void</code>)
</ul><a name="233971"></a>
Evaluation of an expression can also produce side effects, because expressions may contain embedded assignments, increment operators, decrement operators, and method invocations.<p>
<a name="229523"></a>
An expression denotes nothing if and only if it is a method invocation <a href="15.doc.html#20448">(§15.11)</a> that invokes a method that does not return a value, that is, a method declared <code>void</code> <a href="8.doc.html#40420">(§8.4)</a>. Such an expression can be used only as an expression statement <a href="14.doc.html#5984">(§14.7)</a>, 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.<p>
<a name="39859"></a>
Each expression occurs in the declaration of some (class or interface) type that is being declared: in a field initializer, in a static initializer, in a constructor declaration, or in the code for a method.<p>
<a name="229188"></a>
<h2>15.2 Variables as Values</h2>
<a name="229204"></a>
If an expression denotes a variable, and a value is required for use in further evaluation,
then the value of that variable is used. In this context, if the expression
denotes a variable or a value, we may speak simply of the <i>value</i> of the expression.
<p><a name="198550"></a>
<h2>15.3 Type of an Expression</h2>
<a name="229255"></a>
If an expression denotes a variable or a value, then the expression has a type
known at compile time. The rules for determining the type of an expression are
explained separately below for each kind of expression.
<p><a name="229277"></a>
The value of an expression is always assignment compatible <a href="5.doc.html#170768">(§5.2)</a> with the type of the expression, just as the value stored in a variable is always compatible with the type of the variable. In other words, the value of an expression whose type is <i>T</i> is always suitable for assignment to a variable of type <i>T</i>.<p>
<a name="79417"></a>
Note that an expression whose type is a class type <i>F</i> that is declared <code>final</code> is guaranteed to have a value that is either a null reference or an object whose class is <i>F</i> itself, because <code>final</code> types have no subclasses.<p>
<a name="233992"></a>
<h2>15.4 Expressions and Run-Time Checks</h2>
<a name="233993"></a>
If the type of an expression is a primitive type, then the value of the expression is
of that same primitive type. But if the type of an expression is a reference type,
then the class of the referenced object, or even whether the value is a reference to
an object rather than <code>null</code>, is not necessarily known at compile time. There are a
few places in the Java language where the actual class of a referenced object
affects program execution in a manner that cannot be deduced from the type of the
expression. They are as follows:
<p><ul><a name="79422"></a>
<li>Method invocation <a href="15.doc.html#20448">(§15.11)</a>. The particular method used for an invocation <code>o.m(</code>...<code>)</code> is chosen based on the methods that are part of the class or interface that is the type of <code>o</code>. For instance methods, the class of the object referenced by the run-time value of <code>o</code> participates because a subclass may override a specific method already declared in a parent class so that this overriding method is invoked. (The overriding method may or may not choose to further invoke the original overridden <code>m</code> method.)
<a name="79436"></a>
<li>The <code>instanceof</code> operator <a href="15.doc.html#80289">(§15.19.2)</a>. An expression whose type is a reference type may be tested using <code>instanceof</code> to find out whether the class of the object referenced by the run-time value of the expression is assignment compatible <a href="5.doc.html#170768">(§5.2)</a> with some other reference type.
<a name="35797"></a>
<li>Casting (<a href="5.doc.html#176921">§5.4</a>, <a href="15.doc.html#238146">§15.15</a>). 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 error if the class of the referenced object, as determined at run time, is not assignment  compatible <a href="5.doc.html#170768">(§5.2)</a> with the target type.
<a name="35800"></a>
<li>Assignment to an array component of reference type (<a href="10.doc.html#11430">§10.10</a>, <a href="15.doc.html#239587">§15.12</a>, <a href="15.doc.html#5295">§15.25.1</a>). The type-checking rules allow the array type <i>S</i><code>[]</code> to be treated as a subtype of <i>T</i><code>[]</code> if <i>S</i> is a subtype of <i>T</i>, but this requires a run-time check for assignment to an army component, similar to the check performed for a cast.
<a name="79438"></a>
<li>Exception handling <a href="14.doc.html#79311">(§14.18)</a>. An exception is caught by a <code>catch</code> clause only if the class of the thrown exception object is an <code>instanceof</code> the type of the formal parameter of the <code>catch</code> clause.
</ul><a name="35847"></a>
The first two of the cases just listed ought never to result in detecting a type error.
Thus, a Java run-time type error can occur only in these situations:
<p><ul><a name="79443"></a>
<li>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 (<a href="5.doc.html#176921">§5.4</a>, <a href="15.doc.html#238146">§15.15</a>); in this case a <code>ClassCastException</code> is thrown.
<a name="79444"></a>
<li>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 (<a href="10.doc.html#11430">§10.10</a>, <a href="15.doc.html#239587">§15.12</a>, <a href="15.doc.html#5295">§15.25.1</a>); in this case an <code>ArrayStoreException</code> is thrown.
<a name="79445"></a>
<li>When an exception is not caught by any <code>catch</code> handler <a href="11.doc.html#44153">(§11.3)</a>; in this case the thread of control that encountered the exception first invokes the method <code>uncaughtException</code>  <a href="javalang.doc19.html#2901">(§20.21.31)</a> for its thread group and then terminates.
</ul><a name="79448"></a>
<h2>15.5 Normal and Abrupt Completion of Evaluation</h2>
<a name="79449"></a>
Every expression has a normal mode of evaluation in which certain computational
steps are carried out. The following sections describe the normal mode of evaluation
for each kind of expression. If all the steps are carried out without an exception
being thrown, the expression is said to <i>complete normally</i>.
<p><a name="217304"></a>
If, however, evaluation of an expression throws an exception, then the expression is said to <i>complete abruptly</i>. An abrupt completion always has an associated <i>reason</i>, which is always a <code>throw</code> with a given value.<p>
<a name="217294"></a>
Run-time exceptions are thrown by the predefined operators as follows:<p>
<ul><a name="43791"></a>
<li>A class instance creation expression <a href="15.doc.html#41147">(§15.8)</a>, array creation expression <a href="15.doc.html#46168">(§15.9)</a>, or string concatenation operatior expression <a href="15.doc.html#39990">(§15.17.1)</a> throws an <code>OutOfMemoryError</code> if there is insufficient memory available.
<a name="43795"></a>
<li>An array creation expression throws an <code>ArrayNegativeSizeException</code> if the value of any dimension expression is less than zero <a href="15.doc.html#46168">(§15.9)</a>.
<a name="43780"></a>
<li>A field access <a href="15.doc.html#41267">(§15.10)</a> throws a <code>NullPointerException</code> if the value of the object reference  expression is <code>null</code>.
<a name="43784"></a>
<li>A method invocation expression <a href="15.doc.html#20448">(§15.11)</a> that invokes an instance method throws a <code>NullPointerException</code> if the target reference is <code>null</code>.
<a name="43730"></a>
<li>An array access <a href="15.doc.html#239587">(§15.12)</a> throws a <code>NullPointerException</code> if the value of the array reference  expression is <code>null</code>.
<a name="43758"></a>
<li>An array access <a href="15.doc.html#239587">(§15.12)</a> throws an <code>IndexOutOfBoundsException</code> if the value  of the array index expression is negative or greater than or equal to the <code>length</code> of the array.
<a name="217340"></a>
<li>A cast <a href="15.doc.html#238146">(§15.15)</a> throws a <code>ClassCastException</code> if a cast is found to be impermissible at run time.
<a name="217346"></a>
<li>An integer division <a href="15.doc.html#5047">(§15.16.2)</a> or integer remainder <a href="15.doc.html#24956">(§15.16.3)</a> operator throws an <code>ArithmeticException</code> if the value of the right-hand operand expression is zero.
<a name="234027"></a>
<li>An assignment to an array component of reference type <a href="15.doc.html#5295">(§15.25.1)</a> throws an <code>ArrayStoreException</code> when the value to be assigned is not compatible with the component type of the array.
</ul><a name="21217"></a>
A method invocation expression can also result in an exception being thrown if an
exception occurs that causes execution of the method body to complete abruptly.
A class instance creation expression can also result in an exception being thrown
if an exception occurs that causes execution of the constructor to complete
abruptly. Various linkage and virtual machine errors may also occur during the
evaluation of an expression. By their nature, such errors are difficult to predict and
difficult to handle.
<p><a name="6969"></a>
If an exception occurs, then evaluation of one or more expressions may be terminated before all steps of their normal mode of evaluation are complete; such expressions are said to complete abruptly. The terms "complete normally" and  "complete abruptly" are also applied to the execution of statements <a href="14.doc.html#5894">(§14.1)</a>. A  statement may complete abruptly for a variety of reasons, not just because an exception is thrown.<p>
<a name="79456"></a>
If evaluation of an expression requires evaluation of a subexpression, abrupt completion of the subexpression always causes the immediate abrupt completion of the expression itself, with the same reason, and all succeeding steps in the normal mode of evaluation are not performed.<p>
<a name="4779"></a>
<h2>15.6 Evaluation Order</h2>
<a name="40055"></a>
Java guarantees that the operands of operators appear to be evaluated in a specific
<i>evaluation order</i>, namely, from left to right.
<p><a name="18532"></a>
It is recommended that Java code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost  operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.<p>
<a name="18498"></a>
<h3>15.6.1 Evaluate Left-Hand Operand First</h3>
<a name="4781"></a>
The left-hand operand of a binary operator appears to be fully evaluated before
any part of the right-hand operand is evaluated. For example, if the left-hand operand
contains an assignment to a variable and the right-hand operand contains a
reference to that same variable, then the value produced by the reference will
reflect the fact that the assignment occurred first.
<p><a name="18540"></a>
Thus:<p>
<pre><a name="18537"></a>
class Test {
<a name="45395"></a> public static void main(String[] args) {
<a name="18572"></a> int i = 2;
<a name="18538"></a> int j = (i=3) * i;
<a name="18573"></a> System.out.println(j);
<a name="18574"></a> }
<a name="18575"></a>}
</pre><a name="18539"></a>
prints:
<p><pre><a name="45398"></a><code>9
</code></pre><a name="35994"></a>
It is not permitted for it to print <code>6</code> instead of <code>9</code>.
<p><a name="240786"></a>
If the operator is a compound-assignment operator <a href="15.doc.html#5304">(§15.25.2)</a>, then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied combining operation. So, for example, the test program:<p>
<pre><a name="18711"></a>
class Test {
<a name="18712"></a> public static void main(String[] args) {
<a name="18713"></a> int a = 9;
<a name="18714"></a> a += (a = 3); // first example
<a name="18715"></a> System.out.println(a);
<a name="18716"></a> int b = 9;
<a name="18717"></a> b = b + (b = 3); // second example
<a name="18718"></a> System.out.println(b);
<a name="18719"></a> }
<a name="18720"></a>}
</pre><a name="18725"></a>
prints:
<p><pre><a name="18726"></a>
12
<a name="18727"></a>12
</pre><a name="18728"></a>
because the two assignment statements both fetch and remember the value of the
left-hand operand, which is <code>9</code>, before the right-hand operand of the addition is
evaluated, thereby setting the variable to <code>3</code>. It is not permitted for either example
to produce the result <code>6</code>. Note that both of these examples have unspecified behavior
in C, according to the ANSI/ISO standard.
<p><a name="4782"></a>
If evaluation of the left-hand operand of a binary operator completes abruptly, no part of the right-hand operand appears to have been evaluated.<p>
<a name="18857"></a>
Thus, the test program:<p>
<pre><a name="18860"></a>
class Test {
<a name="18861"></a>
public static void main(String[] args) {
<a name="18877"></a>
int j = 1;
<a name="18863"></a>
try {
<a name="18864"></a> int i = forgetIt() / (j = 2);
<a name="18865"></a> } catch (Exception e) {
<a name="36034"></a> System.out.println(e);
<a name="18866"></a> System.out.println("Now j = " + j);
<a name="18867"></a> }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -