为什么Java的main方法是静态的?

新手上路,请多包涵

Java main 方法的方法签名是:

 public static void main(String[] args) {
    ...
}

这个方法必须是静态的有什么原因吗?

原文由 Alotor 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 469
2 个回答

该方法是静态的,否则会产生歧义:应该调用哪个构造函数?特别是如果你的班级是这样的:

 public class JavaClass{
  protected JavaClass(int x){}
  public void main(String[] args){
  }
}

JVM 应该调用 new JavaClass(int) 吗?它应该传递什么 x

如果不是,JVM 是否应该在不运行任何构造方法的情况下实例化 JavaClass ?我认为不应该,因为这将对您的整个类进行特殊处理——有时您有一个尚未初始化的实例,并且您必须在每个可以调用的方法中检查它。

对于 JVM 来说,在调用入口点之前必须实例化一个类有太多的边缘情况和歧义。这就是为什么 main 是静态的。

我不知道为什么 main 总是被标记为 public 虽然。

原文由 Jacob Krall 发布,翻译遵循 CC BY-SA 3.0 许可协议

这只是惯例。事实上,即使是名称 main() 和传入的参数也完全是约定俗成的。

当您运行 java.exe(或 Windows 上的 javaw.exe)时,真正发生的是几个 Java 本机接口 (JNI) 调用。这些调用加载真正是 JVM 的 DLL(没错——java.exe 不是 JVM)。 JNI 是我们在连接虚拟机世界和 C、C++ 等世界时使用的工具……反之亦然——不可能(至少据我所知)实际获得一个JVM 在不使用 JNI 的情况下运行。

基本上,java.exe 是一个超级简单的 C 应用程序,它解析命令行,在 JVM 中创建一个新的字符串数组来保存这些参数,解析出您指定为包含 main() 的类名,使用 JNI 调用来查找main() 方法本身,然后调用 main() 方法,传入新创建的字符串数组作为参数。这非常非常类似于您在 Java 中使用反射时所做的事情——它只是使用容易混淆的本地函数调用。

编写自己的 java.exe 版本(源代码与 JDK 一起分发)并让它做一些完全不同的事情是完全合法的。事实上,这正是我们对所有基于 Java 的应用程序所做的。

我们的每个 Java 应用程序都有自己的启动器。我们主要这样做是为了获得我们自己的图标和进程名称,但在其他情况下它会派上用场,除了常规的 main() 调用之外我们还想做一些事情来让事情继续进行(例如,在一种情况下我们正在做COM 互操作性,我们实际上将 COM 句柄而不是字符串数组传递给 main()。

所以,总而言之:它是静态的原因是 b/c 这很方便。它被称为“main”的原因是它必须是某种东西,而 main() 是他们在 C 的旧时代所做的(在那些日子里,函数的名称 重要)。我想 java.exe 可能只允许您指定一个完全限定的主要方法名称,而不仅仅是类 (java com.mycompany.Foo.someSpecialMain) - 但这只会让 IDE 更难自动检测 ‘项目中的可启动类。

原文由 Kevin Day 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题