为什么Java规范只希望程序的主方法无效?

2022-09-02 00:00:30

尽管返回类型不是方法签名的一部分,但 JVM 会查找确切的声明

 public static void main(String[] args)

我的假设是,由于方法签名不包含“返回类型”,因此必须允许我更改返回类型。

但是,如果我将其更改为并返回一个值,例如0,JVM将无法执行程序并退出并出现错误public static int main(String[] args)

Error: Main method must return a value of type void in class TestData, please 
define the main method as:
   public static void main(String[] args)

为什么 Java 规范只希望 main 方法无效?当返回类型不是方法签名的一部分时,为什么会有此限制?

这个问题与为什么java中的main()无效不同?:这个问题是封闭的,因为它是基于意见的,而我正在寻找JVM调用此方法的代码位置/进程,以及迫使他们保持此方法无效的限制是什么。他们做出的设计决策是什么(以及背后的原因),以及在哪里记录下来。

我正在寻找事实,以便知道为什么这样做。请不要在没有通过问题细节的情况下将其标记为重复。

PS:退出,是另一回事。我更关心的是该计划的进入。此外,返回的值可能不是使用 JVM,将其限制为 void 限制了可扩展性。

到目前为止,我从这个问题中学到的是:Java规范已经明确地固定了返回类型,以避免混淆迁移程序员(C / CPP),他们可能期望这个值返回到操作系统,但由于JVM介于两者之间,这个值永远不会返回给OS。出于这个特殊目的(向操作系统返回值),他们提供了System.exit()方法。


对于那些建议返回类型是签名一部分的人 - 只需尝试在类中定义以下两种方法

    public static void main(String[] a){

    }
    public static String main(String[] a){

    }

您将收到编译错误,因为这两种方法的签名是相同的。


答案 1

is void 在 JLS 12.1.4 Invoke Test.main 中指定:main

该方法必须声明为 、 和 。mainpublicstaticvoid

有时,为什么的答案,因为规范是这么说的(又名Quod Ego Dixit,或因为我说(Terry Pratchett))。有时语言设计师的决定不可用,我们唯一能做的就是猜测。这也是明显的重复(为什么java中的main()void?)被关闭的原因,因为它主要是基于意见的。

现在,对我来说,显而易见的原因:JLS 12.8程序退出说:

程序将终止其所有活动,并在发生以下两种情况之一时退出:

  • 所有不是守护程序线程的线程都将终止。
  • 一些线程调用类或类的方法,安全管理器不禁止退出操作。exitRuntimeSystem

这意味着方法的结束并不一定意味着程序的结束。方法的返回代码在C等语言中具有众所周知的含义:它是进程退出代码。当方法可能在进程本身结束之前很久就退出时,这种含义不适用。mainmainmain

大多数重要的 Java 应用程序通常都有一个短暂的 main 方法,该方法启动一个或多个长期存在的非守护程序线程。允许来自 Java 方法的返回代码可能意味着一个实际上不存在的含义:返回值是进程退出代码。因此,显式指定必须具有 void 返回类型是一件好事:它可以减少混淆或分配不存在的含义。mainmain


答案 2

毕竟,主要方法可能不是退出点。由于多线程,当主线返回时,球场上仍然有另一个线程使程序保持活动状态。在这种情况下,退出代码毫无意义。


推荐