Short Answer
The return cancel()
statement must return a valid value, but the method declaration void run()
declares that run()
does not return a value; hence, return cancel()
in run()
is an error. The return
statement (without an expression) attempts to transfer control to the caller and is used when the method return type is void
; hence, not an error.
Long Answer
The JLS The *return* Statement
section states:
A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it. [...] A return statement with an Expression must be contained in a method declaration that is declared to return a value (§8.4) or a compile-time error occurs. The Expression must denote a variable or value of some type T, or a compile-time error occurs. The type T must be assignable (§5.2) to the declared result type of the method, or a compile-time error occurs.
The JLS Method Return Type
section states:
The return type of a method declares the type of value a method returns, if it returns a value, or states that the method is void. A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold: [...] * If R1 is void then R2 is void.
The JLS Types, Values, and Variables
chapter, first paragraph states:
The Java programming language is a strongly typed language, which means that every variable and every expression has a type that is known at compile time. Types limit the values that a variable (§4.12) can hold or that an expression can produce, limit the operations supported on those values, and determine the meaning of the operations.
The JLS The Kinds of Types and Values
section states:
There are two kinds of types in the Java programming language: primitive types (§4.2) and reference types (§4.3). There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values (§4.2) and reference values (§4.3).
Just a few more quotes now. The JLS Expression Statements
section states:
Unlike C and C++, the Java programming language allows only certain forms of expressions to be used as expression statements. Note that the Java programming language does not allow a "cast to void"-void is not a type
The JLS Method Body
section states:
If a method is declared void, then its body must not contain any return statement (§14.17) that has an Expression.
And, finally, the JLS Method Declarations
section states:
A method declaration either specifies the type of value that the method returns or uses the keyword void to indicate that the method does not return a value.
Now, when we piece it all together, we can deduce the following:
- If a
return
statement contains an expression, the expression must evaluate to a valid value.
- A valid
return
expression value must be a primitive type or a reference type.
void
is not a valid value type.
- A method declared with a
void
return type, returns no value.
- Method
void run()
does not return a value.
- In
run()
, return
, without an expression, will happily transfer control to the caller.
- In
run()
, return some expression
is an error because some expression
must be a valid value and run()
does not return a value.