一尘不染

为什么Java主要方法是静态的?

java

Java main()方法的方法签名为:

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

此方法是否有理由是静态的?


阅读 479

收藏
2020-02-27

共2个答案

一尘不染

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

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

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

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

对于JVM,在调用入口点之前必须实例化一个类,这有太多的极端情况和含糊之处。这就是为什么main是静态的。

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

2020-02-27
一尘不染

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

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

基本上,java.exe是一个超级简单的C应用程序,它解析命令行,在JVM中创建一个新的String数组来保存这些参数,解析出您指定为包含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很难自动检测“项目中的“可启动”类。

2020-02-27