🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Java `main()`方法 > 原文: [https://howtodoinjava.com/java/basics/main-method/](https://howtodoinjava.com/java/basics/main-method/) 您是否曾经尝试过说明 **Java `main()`方法**是`public`,`static`和`void`的原因? 为什么叫`main`? 当您调用`main()`方法时,JVM 内部会发生什么? `main()`方法的**目的**是什么? 让我们找出答案。 ```java Table of Contents 1\. Java main method syntax 2\. Why main method is public? 3\. Why main method is static? 4\. Why main method is void? 5\. Why the name is main? 6\. What happens internally when you invoke main method? 7\. main() method native code in java.c 8\. Do we always need main method to run java program? 9\. Summary ``` ## 1\. Java `main()`方法语法 首先提醒一下 Java 中`main`方法的**语法**。 ```java public class Main { public static void main(String[] args) { System.out.println("Hello World !!"); } } ``` ## 2\. 为什么 Java `main()`方法是公开的? 这个大问题也许也是最困难的。 我尽力在我能获得的所有良好学习材料中找到找到此问题的一个很好的理由,但没有任何证据被证明是足够的。 因此,我的分析(与许多其他方法一样)说:**`main()`方法是公共的,因此可以在任何地方以及可能希望使用它启动应用程序**的每个对象中访问。 在这里,我并不是说 JDK / JRE 具有类似的原因,因为`java.exe`或`javaw.exe`(对于 Windows)使用 **Java 本机接口**(JNI)对`invoke`方法的调用,因此无论使用哪种访问修饰符,它们都可以被调用。 回答这个问题的第二种方法是另一个问题,为什么不公开? Java 中的所有方法和构造器都有一些访问修饰符。 `main()`方法也需要一个。 没有理由不应该将其设置为`public`,而应使用任何其他修饰符(默认/受保护/私有)。 请注意,如果不使用`main()`方法`public`,则不会发生编译错误。 您将出现**运行时错误**,因为不存在匹配的`main()`方法。 请记住,整个语法应该匹配才能执行`main()`方法。 ```java public class Main { void static main(String[] args) { System.out.println("Hello World !!"); } } ``` 程序输出: ```java Error: Main method not found in class Main, please define the main method as: public static void main(String[] args) ``` ## 3\. 为什么 Java `main()`方法是静态的? 另一个大问题。 为了理解这一点,假设我们没有`main`方法为`static`。 现在,要调用任何方法,您需要它的一个实例。是吧? **众所周知,Java 可以具有重载的构造器。 现在,应该使用哪一个,重载的构造器的参数将从何处来**。 这些只是更困难的问题,这些问题帮助 Java 设计人员下定了决心,并将`main()`方法设为`static`。 请注意,如果不使用`main()`方法`static`,则不会发生编译错误。 您将**运行时错误**。 ```java public class Main { public void main(String[] args) { System.out.println("Hello World !!"); } } ``` 程序输出: ```java Error: Main method is not static in class main, please define the main method as: public static void main(String[] args) ``` ## 4\. 为什么 Java `main()`方法是`void`? 为什么不应该无效? 您是否从代码中调用过此方法? 没有。 **因此,没有任何将值返回给实际调用此方法**的 JVM 的用途。 它根本不需要任何返回值。 应用程序唯一想与调用过程进行通信的是正常终止还是异常终止。 使用`System.exit(int)`已经可以做到这一点。 非零值表示异常终止,否则一切正常。 ## 5\. 为什么名字叫`main`? 没有坚如磐石的理由。 假设因为**它已经与 C 和 C++ 语言**一起使用。 因此,大多数开发人员已经对这个名称感到满意。 否则,没有其他充分的理由。 ## 6\. 调用`main`方法在内部会发生什么? Java 中`main()`方法的**用途是程序执行的起点**。 当您运行`java.exe`,然后运行**时,有几个 Java 本机接口(JNI)调用**。 这些调用会加载真正是 JVM 的 DLL(是的-`java.exe`不是 JVM)。 JNI 是我们在虚拟机世界和 C,C++ 等世界之间架起桥梁时所使用的工具。反之亦然。 如果不使用 JNI,就不可能真正使 JVM 运行。 基本上,`java.exe`是一个超级简单的 C 应用程序,解析命令行,在 JVM 中创建一个新的`String`数组来保存这些参数,解析出您指定来包含`main()`的类名,使用 JNI 调用来查找`main()`方法本身,然后调用`main()`方法,传入新创建的字符串数组作为参数。 这非常类似于使用 Java 反射时的操作,只是使用了令人困惑的命名本机函数调用。 > 对于您来说,编写自己的`java.exe`版本(源代码随 JDK 分发)并执行完全不同的操作是完全合法的。 ## 7\. `java.c`中的`main()`方法本机代码 下载并解压缩源 jar 并签出`../launcher/java.c`。 它是这样的: ```java /* * Get the application's main class. */ if (jarfile != 0) { mainClassName = GetMainClassName(env, jarfile); ... ... mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ... ... /* Get the application's main method */ mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); ... ... {/* Make sure the main method is public */ jint mods; jmethodID mid; jobject obj = (*env)->ToReflectedMethod(env, mainClass, mainID, JNI_TRUE); ... ... /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); if (mainArgs == NULL) { ReportExceptionDescription(env); goto leave; } /* Invoke main method. */ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); ``` 因此,在这里您可以看到**用`main`方法**调用 Java 程序时会发生什么。 ## 8\. 我们是否总是需要`main`方法来运行 Java 程序? 我相信不是。 我们有 applet,在这里我们没有编写`main`方法。 我仍然需要检查它们是如何执行的。 如果您已经知道,请与我分享。 ## 9\. 总结 所有开发人员都使用 Java 的`main`方法,每个人都知道编写它的基本语法。 但是,很少有人完全理解正确的推理及其工作方式。 我仍在努力寻求更多的理解,如果发现更多有趣的事实,将更新这篇文章。 如果您有什么要分享的内容,请在评论部分添加或给我发送邮件。 在这篇文章中,我将包含在您的知识中。 学习愉快! 参考: [StackOverflow](https://stackoverflow.com/questions/146576/why-is-the-java-main-method-static?page=1&tab=votes#tab-top "source information")