简答
return cancel() 语句必须返回有效值,但方法声明void run() 声明run() 不返回值;因此,run() 中的 return cancel() 是一个错误。 return 语句(不带表达式)尝试将控制权转移给调用者,并在方法返回类型为 void 时使用;因此,不是错误。
长答案
JLSThe *return* Statement section 声明:
没有 Expression 的 return 语句尝试将控制权转移给包含它的方法或构造函数的调用者。 [...] 带有 Expression 的 return 语句必须包含在声明为返回值(第 8.4 节)的方法声明中,否则会发生编译时错误。表达式必须表示某个类型 T 的变量或值,否则会发生编译时错误。类型 T 必须可分配(第 5.2 节)到方法的声明结果类型,否则会发生编译时错误。
JLS Method Return Type section 声明:
方法的返回类型声明一个方法返回的值的类型,如果它返回一个值,或者声明该方法是无效的。当且仅当以下条件成立时,具有返回类型 R1 的方法声明 d1 可以返回类型替代具有返回类型 R2 的另一个方法 d2:[...] * 如果 R1 为 void,则 R2 为 void。
JLS Types, Values, and Variables chapter,第一段指出:
Java 编程语言是一种强类型语言,这意味着每个变量和每个表达式都具有在编译时已知的类型。类型限制变量(第 4.12 节)可以保存的值或表达式可以产生的值,限制这些值支持的操作,并确定操作的含义。
JLS The Kinds of Types and Values section 声明:
Java 编程语言中有两种类型:原始类型(第 4.2 节)和引用类型(第 4.3 节)。相应地,有两种数据值可以存储在变量中、作为参数传递、由方法返回和操作:原始值(第 4.2 节)和参考值(第 4.3 节)。
现在再多引用几句。 JLS Expression Statements section 声明:
与 C 和 C++ 不同,Java 编程语言只允许将某些形式的表达式用作表达式语句。请注意,Java 编程语言不允许“强制转换为 void”-void 不是类型
JLS Method Body section 声明:
如果方法被声明为 void,则其主体不得包含任何具有表达式的返回语句(第 14.17 节)。
最后,JLS Method Declarations section 声明:
方法声明要么指定方法返回的值的类型,要么使用关键字 void 表示方法不返回值。
现在,当我们将它们拼凑在一起时,我们可以得出以下结论:
- 如果
return 语句包含表达式,则表达式的计算结果必须为有效值。
- 有效的
return 表达式值必须是基本类型或引用类型。
-
void 不是有效的值类型。
- 使用
void 返回类型声明的方法不返回任何值。
- 方法
void run() 不返回值。
- 在
run()、return 中,不带表达式,很乐意将控制权转移给调用者。
- 在
run() 中,return some expression 是错误的,因为some expression 必须是有效值,而run() 不返回值。