void 方法不能 return void 方法的值?

Void methods can't return the value of a void method?

看不懂不介意,但我想知道为什么会这样:

void something(String a) {
    return hi();
}
void hi() {
    return;
}

奇怪的是,hi() 也有一个 return 类型的 void。我在 IDE:

中收到语法错误
Void methods cannot return a value

此外,代码无法编译:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Void methods cannot return a value

    at Resources.setSystemProperties(Resources.java:33)
    at Resources.main(Resources.java:49)

我希望这会发生:

hi() -> return nothing

return [nothing] -> hi() is nothing

所以最后,它 return 没什么,就像 void 方法应该的那样。

为什么会发生这种行为?当 return void 方法的结果时,为什么代码不编译?

声明为 void 的函数不能 return 任何东西,就像错误所说的那样。您假设 a.notify() return 任何东西都是错误的,因为 a.notify() 也不能 return 任何东西(因为它是无效的)。

因为这就是语言的工作原理。您不能使用 return 关键字来 return 具有 return 类型 void 的方法中的值。 void is not a real value that can be passed around:

The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.

这是an article by James Iry comparing void in Java with Unit in Scala。 (与 void 不同,unit 是一个可以 returned 的实际值。)他证明了使用 Unit 类型而不是 void 有很多优势:

Java, C++, and C# programmers do solve this problem all the time. One common option is to not use Function but some other concept like "Action" to mean a function that takes a string, performs a side effect, and returns nothing useful. Then you essentially duplicate "map" into something called perhaps "foreach" that expects an Action and returns void. That probably makes sense in this case since a list of references to a meaningless value is perhaps silly, but it also means a great deal of code duplication if this kind of higher order programming is common. For instance, you can't write just one compose function that creates a function from two other functions, you also have to write a compose that takes an action and a function to create an action.

Java 编译器不会去那么深入。当它在 void 函数中看到 return 关键字后面有一些值时,它将抛出编译错误。它是这样编程的。就如此容易。

return  statements simply cannot be used with `Void` as it's Return type.

您不能更改语言规则!

这是在JLS 14.17中定义的:

A return statement with an Expression must be contained in one of the following, or a compile-time error occurs:

  • A method that is declared to return a value
  • A lambda expression

void 方法未声明为 return 值,因此 return 带有表达式的语句(如函数调用)不会发生在此类方法中。

此外,由于 JLS 15.12.3 中的这种语言,您不能 return void 方法的结果:

If the compile-time declaration is void, then the method invocation must be a top level expression (that is, the Expression in an expression statement or in the ForInit or ForUpdate part of a for statement), or a compile-time error occurs.

换句话说,由于 a.notify()void,您可以在它看起来像一个语句的上下文中使用它(即,单独一行),但不能在它看起来像的上下文中使用它就像一个表达式(即,你不能将它的值赋给一个变量,return 它,等等)。