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

Why does Java Specifications want the main method of a program to be void only?

尽管 return 类型不是方法签名的一部分,但 JVM 会查找与

完全相同的声明
 public static void main(String[] args)

我的假设是,由于方法签名没有包含 "return type",我必须是 允许更改 return 类型。

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

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 方法无效? 当 return 类型不是方法签名的一部分时,为什么会有此限制?

此问题与 Why is main() in java void? 不同:此问题已关闭,因为它是基于意见的,而我正在寻找 JVM 调用此方法的代码位置/进程,以及有哪些限制迫使他们将此方法保持为无效。他们做出了哪些设计决策(以及背后的原因),记录在何处。

我正在寻找事实,以了解这样做的原因。 请不要在未查看问题详细信息的情况下将其标记为重复。

PS:退出,是另外一回事。我比较关心程序的入口。此外,returned 值可能不适用于 JVM,将其限制为无效限制了可扩展性。

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


对于所有建议 return 类型是签名的一部分的人——只需尝试在 class

中定义以下两种方法
    public static void main(String[] a){

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

    }

你会得到一个编译错误,因为这两个方法的签名是一样的。

您不能从 Java 文档中查看下面的内容,要使您的 main 方法充当退出点,您需要使该方法无效。或者您可以选择在 main.

结束时显式调用 system.exit()

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

如果您要求 JVM 运行 一个 class,java 运行时间将在您的 class public static void main(String[] args) 那就是你和JVM的契约,如果不是,它就不会执行。 如果你想要一个 int 代码,使用 System.exit

如中所述 http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.8

12.8. Program Exit

A program terminates all its activity and exits when one of two things happens:

All the threads that are not daemon threads terminate.

Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.

如果所有 运行 线程都是守护进程,程序将退出。所以如果你有一个非守护线程,main 方法可能会在程序结束前 return。

您的程序的生命周期可以延长 main 方法的生命周期,return 数量可能会在程序的后期决定。

我认为这就是他们使用 System.exit() 作为 return 点的原因。

main 方法可能不是一个退出点。由于多线程,当 main returns 时,球场上可能还有另一个线程保持程序运行。在这种情况下退出代码没有意义。

JLS 12.1.4 Invoke Test.main中指定main无效:

The method main must be declared public, static, and void.

有时 为什么? 的答案是 因为规范是这样说的(又名 Quod Ego Dixit,或者因为我这么说(特里普拉切特))。有时语言设计者的决定是不可用的,我们唯一能做的就是猜测。这也是明显重复 (Why is main() in java void?) 主要基于意见而被关闭的原因。

现在 - 对我来说 - 显而易见的原因:JLS 12.8 Program Exit 说:

A program terminates all its activity and exits when one of two things happens:

  • All the threads that are not daemon threads terminate.
  • Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.

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

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

我们可以说,main 方法作为 class 初始化方法,因为它满足 class 初始化标准之一;请参考http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.412.4.1部分--

T 是一个 class 并且调用了 T 声明的静态方法。

现在,根据 JVM 规范,return 指令用于 return 来自声明为 void 的方法、实例初始化方法、和class或接口初始化方法http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.11.8

请在此处查看有关 return 指令的详细信息:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.1.9.return

Java 被设计为 Platform independent language。因此,如果它是 main() 方法 return 的值(例如 0 或 1 或任何值),则不同的平台可能会对其进行不同的解释或理解。因此,与 CCpp 不同,它的 main() 方法不能 return 一个值。

为什么无效?

如果你想 return 一些状态到 OS 你可以使用任何现有的 methods.Most 常见的 System.exit(int status) .

如果您的主线程在其他线程之前完成,则 return 值无关紧要。 这与当时不支持多线程的 c/c++ 形成对比。

像 swing 应用程序可能在完成 main 后仍然可以在 EDT 上工作。

如果你还在考虑"entry"点:但是return类型总是谈论退出。

所以它只是无效的,因为我们有状态信号器 return 一个值或没有 return 在其他情况下。 尽管如此,没有其他意义,因为它是在这个 way.Another 中设计的,具有不同想法的开发人员可能会提出另一个想法来解决相同的问题 situation.Depends。

据我所知,

main方法的void类型为return的原因是,一旦main方法执行完毕,并不意味着整个程序完成。它可能启动了一些线程并在幕后 运行。即使主线程死了,子线程还是有机会死掉的运行。在这种情况下,main 的 return 类型没有多大意义。

JVM将监视程序完成状态以释放内存,不需要return某些东西到JVM表明程序已完成。在 C 语言中,我们直接与 O.S 通信。因此,有一个选项可以将 return int 值设置为 O.S。表示执行已完成并开始释放内存。但是在java这里,JVM会和O.S沟通。但不是程序,所以我们不需要 return 来自 main.

的任何东西

希望这能消除您的疑虑。

主要原因是在常见的用例中,尤其是在多线程和 GUI 应用程序中,您不希望在 main 中有一个 return 值。但如果你真的有这样的用例,你可以使用 exit 方法。这就是您正在寻找的原因。

控制台程序 return 是一个 int return 代码,因此在传统的 C 程序中 int main(int argc, char** argv) 似乎合乎逻辑。

在Java中引入了异常作为新的控制流机制,并且还模拟了多线程或者现在实施。 System.exit(int returnCode).

到处都可以退出

这意味着对 main 的调用嵌入在一段代码中,最干净的(简约,案例少,没有 return 0 的魔力)是 default 的 returning 0,除了 System.exit.

请注意,java 旨在强烈 "improve" C,尤其是 C++。就像让字符串和字符使用完整的 Unicode 而不是字节。

What is main method in Java?

Java 中的 Main 方法是任何核心 Java 程序的入口点。请记住,我们 不是在谈论 Servlet、MIDlet 或任何其他容器管理的 Java 程序,其中提供了生命周期方法来控制执行 。在核心 Java 程序中,当您键入 java main-class-name 时,从 main 方法开始执行,JVM 搜索 public static void main(String args[]) 方法 在那个 class 和 如果它没有找到 那个方法它 抛出错误 NoSuchMethodError:main 并终止。

Java

中主要方法的签名

Main 方法必须严格遵循其语法;否则 JVM 将无法找到它,您的程序也不会 运行。这是 main 方法的确切签名:

public static void main(String args[])

此签名是 classic 签名,从 Java 开始,但在 Java5 中引入了可变参数或可变参数,您还可以在 [=122] 中声明 main 方法=] 使用可变参数语法,如下例所示:

public static void main(String... args)

记住 java main 方法的可变参数版本仅适用于 Java 1.5 或更高版本。除了 public、static 和 void 之外,java main 方法的签名中允许使用某些关键字,如 final、synchronized 和 strictfp。

Why main method is static in Java

为什么 main 方法是 public static void in Java现在回到要点 "Why main method is static in Java",周围有很多原因,但这里有一些有意义的原因我:

  1. 因为 main 方法是静态的 Java 虚拟机可以调用它而无需创建包含 main 方法的 class 的任何实例。

  2. 由于 C 和 C++ 也有类似的 main 方法作为程序执行的入口点,遵循该约定只会有帮助 Java.

  3. 如果 main 方法未声明为静态,则 JVM 必须创建 main Class 的实例,并且由于构造函数可以重载并且可以有参数,因此不会有任何确定且一致的方法JVM在Java.

  4. 中寻找main方法
  5. 在Java中的class中声明的任何东西都属于引用类型,需要在使用它们之前创建对象,但是静态方法和静态数据被加载到单独的内存中在 JVM 中称为上下文,它是在加载 class 时创建的。如果 main 方法是静态的,那么它将被加载到 JVM 上下文中并可用于执行。

Why main mehtod is public in Java

Java 指定多个访问修饰符,例如私有、受保护和 public。在 Java 中声明为 public 的任何方法或变量都可以从 class 外部访问。由于主要方法是 public 在 Java,JVM 可以轻松访问和执行它。

Why main method is void in Java

因为 Java 中的 main 方法不应该 return 任何值,所以它变成了 void,这仅仅意味着 main 没有 returning 任何东西。

总结:

  1. Main 方法必须在Java 中声明为public、static 和void,否则JVM 将无法运行 Java 程序。

  2. 如果 JVM 在提供给 Java 命令的 class 中找不到预定义签名的主要方法,则它会抛出 NoSuchMethodException:main。例如。如果你 运行 java Helloworld 那么 JVM 将在 HelloWorld.class 文件中搜索 public static void main String args[]) 方法。

  3. Main 方法是任何核心 Java 程序的入口点。从main方法开始执行。

4。 Main 方法是运行 由一个名为"main" 的特殊线程在Java 中执行的。您的 Java 程序将 运行ning 直到您的主线程 运行ning 或从 main 方法派生的任何非守护线程 运行ning.

  1. 当您看到“Thread main 中的异常”时,例如 Exception in Thread main: Java.lang.NullPointerException 表示在主线程内部抛出了异常。

  2. 从 Java 1.5 开始,您可以使用可变参数语法声明 main 方法,例如 public static void main(String... args)

  3. 除了 static、void 和 public 之外,您还可以在 Java 中的 main 方法的签名中使用 final、synchronized 和 strictfp 修饰符。

  1. Main method in Java can be overloaded like any other method in Java but JVM will only call main method with specified signature specified above.
  1. 您可以在 main 方法的签名中使用 throws 子句,并且可以抛出任何已检查或未检查的异常。

  2. 甚至在 JVM 调用 main 方法之前执行静态初始化程序块。它们在 JVM 将 Class 加载到内存中时执行。

我希望这已经回答了你关于 main 方法的问题:)

更新响应:

One small problem with your answer: Return type is not a part of method signature.. hence, JVM must not throw the exception "NoSuchMethodException:main" if the return type is different.

如果 return 类型不同并且 return 类型是方法签名的一部分,则 return "NoSuchMethodException:main" 不会。看看这张截图: