Source: https://book.huihoo.com/the-java-language-specification/first-edition/14.doc.html
Timestamp: 2019-04-23 20:34:23+00:00

Document:
The sequence of execution of a Java program is controlled by statements, which are executed for their effect and do not have values.
Blocks are explained first (§14.2), because they can appear in certain places where other kinds of statements are not allowed, and because one other kind of statement, a local variable declaration statement (§14.3), must be immediately contained within a block.
Next a grammatical maneuver is explained that sidesteps the familiar "dangling else" problem (§14.4).
Statements that will be familiar to C and C++ programmers are the empty (§14.5), labeled (§14.6), expression (§14.7), if (§14.8), switch (§14.9), while (§14.10), do (§14.11), for (§14.12), break (§14.13), continue (§14.14), and return (§14.15) statements.
Unlike C and C++, Java has no goto statement. However, the break and continue statements are extended in Java to allow them to mention statement labels.
The Java statements that are not in the C language are the throw (§14.16), synchronized (§14.17), and try (§14.18) statements.
The last section (§14.19) of this chapter addresses the requirement that every statement be reachable in a certain technical sense.
The break (§14.13), continue (§14.14), and return (§14.15) statements cause a transfer of control that may prevent normal completion of statements that contain them.
Evaluation of certain Java expressions may throw exceptions from the Java Virtual Machine; these expressions are summarized in §15.5. An explicit throw (§14.16) statement also results in an exception. An exception causes a transfer of control that may prevent normal completion of statements.
The terms "complete normally" and "complete abruptly" also apply to the evaluation of expressions (§15.5). The only reason an expression can complete abruptly is that an exception is thrown, because of either a throw with a given value (§14.16) or a run-time exception or error (§11, §15.5).
A block is a sequence of statements and local variable declaration statements within braces.
A local variable declaration can also appear in the header of a for statement (§14.12). In this case it is executed in the same manner as if it were part of a local variable declaration statement.
The scope of a local variable declared in a block is the rest of the block, including its own initializer. The name of the local variable parameter may not be redeclared as a local variable or exception parameter within its scope, or a compile-time error occurs; that is, hiding the name of a local variable is not permitted.
There are many kinds of statements in the Java language. Most correspond to statements in the C and C++ languages, but some are unique to Java.
else door.bell.ring();								// A "dangling else"
Statements are thus grammatically divided into two categories: those that might end in an if statement that has no else clause (a "short if statement") and those that definitely do not. Only statements that definitely do not end in a short if statement may appear as an immediate substatement before the keyword else in an if statement that does have an else clause. This simple rule prevents the "dangling else" problem. The execution behavior of a statement with the "no short if" restriction is identical to the execution behavior of the same kind of statement without the "no short if" restriction; the distinction is drawn purely to resolve the syntactic difficulty.
Unlike C and C++, the Java language has no goto statement; identifier statement labels are used with break (§14.13) or continue (§14.14) statements appearing anywhere within the labeled statement.
A statement labeled by an identifier must not appear anywhere within another statement labeled by the same identifier, or a compile-time error will occur. Two statements can be labeled by the same identifier only if neither statement contains the other.
There is no restriction against using the same identifier as a label and as the name of a package, class, interface, method, field, parameter, or local variable. Use of an identifier to label a statement does not hide a package, class, interface, method, field, parameter, or local variable with the same name. Use of an identifier as a local variable or as the parameter of an exception handler (§14.18) does not hide a statement label with the same name.
(void) ... ;								// This idiom belongs to C, not to Java!
does not work in Java. On the other hand, Java allows all the most useful kinds of expressions in expressions statements, and Java does not require a method invocation used as an expression statement to invoke a void method, so such a trick is almost never needed. If a trick is needed, either an assignment statement (§15.25) or a local variable declaration statement (§14.3) can be used instead.
If the value is true, then the contained Statement is executed; the if-then statement completes normally only if execution of the Statement completes normally.
If the value is true, then the first contained Statement (the one before the else keyword) is executed; the if-then-else statement completes normally only if execution of that statement completes normally.
If the value is false, then the second contained Statement (the one after the else keyword) is executed; the if-then-else statement completes normally only if execution of that statement completes normally.
The body of a switch statement must be a block. Any statement immediately contained by the block may be labeled with one or more case or default labels. These labels are said to be associated with the switch statement, as are the values of the constant expressions (§15.27) in the case labels.
At most one default label may be associated with the same switch statement.
case 7:					foo();				// but it's not valid in Java.
If execution of the Statement completes abruptly for any other reason, the switch statement completes abruptly for the same reason. The case of abrupt completion because of a break with a label is handled by the general rule for labeled statements (§14.6).
If execution of the Statement completes abruptly, see §14.10.1 below.
If execution of the Statement completes abruptly for any other reason, the while statement completes abruptly for the same reason. Note that the case of abrupt completion because of a break with a label is handled by the general rule for labeled statements (§14.6).
If execution of the Statement completes abruptly for any other reason, the do statement completes abruptly for the same reason. The case of abrupt completion because of a break with a label is handled by the general rule (§14.6).
If the ForInit code is a list of statement expressions (§14.7), the expressions are evaluated in sequence from left to right; their values, if any, are discarded. If evaluation of any expression completes abruptly for some reason, the for statement completes abruptly for the same reason; any ForInit statement expressions to the right of the one that completed abruptly are not evaluated.
If the ForInit code is a local variable declaration, it is executed as if it were a local variable declaration statement (§14.3) appearing in a block. In this case, the scope of a declared local variable is its own initializer and any further declarators in the ForInit part, plus the Expression, ForUpdate, and contained Statement of the for statement. If execution of the local variable declaration completes abruptly for any reason, the for statement completes abruptly for the same reason.
If execution of the Statement completes abruptly, see §14.12.3 below.
If execution of the Statement completes abruptly for any other reason, the for statement completes abruptly for the same reason. Note that the case of abrupt completion because of a break with a label is handled by the general rule for labeled statements (§14.6).
A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement; this statement, which is called the break target, then immediately completes normally. To be precise, a break statement with no label always completes abruptly, the reason being a break with no label. If no switch, while, do, or for statement encloses the break statement, a compile-time error occurs.
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.6) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a while, do, for, or switch statement. To be precise, a break statement with label Identifier always completes abruptly, the reason being a break with label Identifier. If no labeled statement with Identifier as its label encloses the break statement, a compile-time error occurs.
The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.18) within the break target whose try blocks contain the break statement, then any finally clauses of those try statements are executed, in order, innermost to outermost, before control is transferred to the break target. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a break statement.
A continue statement with no label attempts to transfer control to the innermost enclosing while, do, or for statement; this statement, which is called the continue target, then immediately ends the current iteration and begins a new one. To be precise, such a continue statement always completes abruptly, the reason being a continue with no label. If no while, do, or for statement encloses the continue statement, a compile-time error occurs.
A continue statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.6) that has the same Identifier as its label; that statement, which is called the continue target, then immediately ends the current iteration and begins a new one. The continue target must be a while, do, or for statement or a compile-time error occurs. More precisely, a continue statement with label Identifier always completes abruptly, the reason being a continue with label Identifier. If no labeled statement with Identifier as its label contains the continue statement, a compile-time error occurs.
See the descriptions of the while statement (§14.10), do statement (§14.11), and for statement (§14.12) for a discussion of the handling of abrupt termination because of continue.
The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.18) within the continue target whose try blocks contain the continue statement, then any finally clauses of those try statements are executed, in order, innermost to outermost, before control is transferred to the continue target. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a continue statement.
A return statement returns control to the invoker of a method (§8.4, §15.11) or constructor (§8.6, §15.8).
A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (§8.4), or in the body of a constructor (§8.6). A compile-time error occurs if a return statement appears within a static initializer (§8.5). A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it. To be precise, a return statement with no Expression always completes abruptly, the reason being a return with no value.
A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation. More precisely, execution of such a return statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the return statement completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the return statement completes abruptly, the reason being a return with value V.
The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.18) within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.
A throw statement causes an exception (§11) to be thrown. The result is an immediate transfer of control (§11.3) that may exit multiple statements and multiple constructor, static and field initializer evaluations, and method invocations until a try statement (§14.18) is found that catches the thrown value. If no such try statement is found, then execution of the thread (§17, §20.20) that executed the throw is terminated (§11.3) after invocation of the UncaughtException method (§20.21.31) for the thread group to which the thread belongs.
The throw statement is contained in a method or constructor declaration and the type of the Expression is assignable (§5.2) to at least one type listed in the throws clause (§8.4.4, §8.6.4) of the declaration.
A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the throw statement completes abruptly, the reason being a throw with value V.
If there are any enclosing try statements (§14.18) whose try blocks contain the throw statement, then any finally clauses of those try statements are executed as control is transferred outward, until the thrown value is caught. Note that abrupt completion of a finally clause can disrupt the transfer of control initiated by a throw statement.
If a throw statement is contained in a constructor declaration, but its value is not caught by some try statement that contains it, then the class instance creation expression (or the method invocation of method newInstance of class Class) that invoked the constructor will complete abruptly because of the throw.
If a throw statement is contained in a static initializer (§8.5), then a compile-time check ensures that either its value is always an unchecked exception or its value is always caught by some try statement that contains it. If, despite this check, the value is not caught by some try statement that contains the throw statement, then the value is rethrown if it is an instance of class Error or one of its subclasses; otherwise, it is wrapped in an ExceptionInInitializerError object, which is then thrown (§12.4.2).
By convention, user-declared throwable types should usually be declared to be subclasses of class Exception, which is a subclass of class Throwable (§11.5, §20.22).
A try statement may have catch clauses (also called exception handlers). A catch clause must have exactly one parameter (which is called an exception parameter); the declared type of the exception parameter must be the class Throwable or a subclass of Throwable, or a compile-time error occurs. The scope of the parameter variable is the Block of the catch clause. An exception parameter must not have the same name as a local variable or parameter in whose scope it is declared, or a compile-time error occurs.
The scope of the name of an exception parameter is the Block of the catch clause. The name of the parameter may not be redeclared as a local variable or exception parameter within the Block of the catch clause; that is, hiding the name of an exception parameter is not permitted.
If execution of the try block completes abruptly for any other reason, then the try statement completes abruptly for the same reason.
The NullPointerException (which is a kind of RuntimeException) that is thrown by method blowUp is not caught by the try statement in main, because a NullPointerException is not assignable to a variable of type BlewIt. This causes the finally clause to execute, after which the thread executing main, which is the only thread of the test program, terminates because of an uncaught exception (§20.21.31), which results in printing the exception name and a simple backtrace.
It is a compile-time error if a statement cannot be executed because it is unreachable . Every Java compiler must carry out the conservative flow analysis specified here to make sure all statements are reachable.
even though the value of n is known at compile time and in principle it can be known at compile time that the assignment to k can never be executed. A Java compiler must operate according to the rules laid out in this section.
The block that is the body of a constructor, method, or static initializer is reachable.
If a finally block is present, it is reachable iff the try statement is reachable.
HYPOTHETICAL: An if-then-else statement can complete normally iff the then-statement can complete normally or the else-statement can complete normally. The then-statement is reachable iff the if-then-else statement is reachable and the condition expression is not a constant expression whose value is false. The else statement is reachable iff the if-then-else statement is reachable and the condition expression is not a constant expression whose value is true.
ACTUAL: An if-then-else statement can complete normally iff the then-statement can complete normally or the else-statement can complete normally. The then-statement is reachable iff the if-then-else statement is reachable. The else-statement is reachable iff the if-then-else statement is reachable.

References: §15
 §15
 §14
 §14
 §15
 §15
 V.

 §20
 §8
 V.

 §20