Java主方法的方法签名是:

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

为什么这个方法必须是静态的?


当前回答

这背后的原因很简单,因为对象不需要调用静态方法,如果它是非静态方法,java虚拟机先创建对象,然后调用main()方法,这将导致额外的内存分配问题。

其他回答

在Java中声明为静态的任何方法都属于类本身。 同样,特定类的静态方法只能通过引用类Class_name.method_name();

因此,在访问静态方法之前不需要实例化类。

因此main()方法被声明为静态的,这样就可以在不创建该类对象的情况下访问它。

因为我们用存在main方法的类名来保存程序(或者从程序开始执行的地方开始,适用于没有main()方法()的类(高级级别))。所以通过上面提到的方法:

Class_name.method_name();

可以访问主方法。

简而言之,当程序被编译时,它会在类中搜索main()方法,其String参数如下:main(String args[])。由于在开始时它没有实例化该类的作用域,因此main()方法被声明为静态的。

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

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

JVM是否应该调用新的JavaClass(int)?x应该通过什么?

如果不是,JVM是否应该实例化JavaClass而不运行任何构造函数方法?我认为不应该这样,因为那样会使你的整个类出现特殊情况——有时你有一个没有初始化的实例,你必须在每个可能被调用的方法中检查它。

在调用入口点之前,JVM必须实例化一个类,这有太多的边缘情况和模糊性,因此没有意义。这就是为什么main是静态的。

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

各种类型的applet、midlet、servlet和bean被构造,然后在它们上调用生命周期方法。调用main是对主类所做的全部工作,因此不需要在被多次调用的对象中保存状态。将main固定在另一个类上是很正常的(尽管这不是一个好主意),这将妨碍使用类创建main对象。

让我们简单地假设,静态不需要作为应用程序入口点。

一个应用程序类看起来是这样的:

class MyApplication {
    public MyApplication(){
        // Some init code here
    }
    public void main(String[] args){
        // real application code here
    }
}

构造函数代码和主方法之间的区别是必要的,因为在OO中,构造函数只应确保实例被正确初始化。初始化后,实例可以用于预期的“服务”。将完整的应用程序代码放到构造函数中会破坏这一点。

因此,这种方法将在应用程序上强制执行三个不同的契约:

必须有一个默认构造函数。否则,JVM将不知道调用哪个构造函数以及应该提供哪些参数。 必须有一个主要的方法。好吧,这并不奇怪。 类不能是抽象的。否则,JVM无法实例化它。

另一方面,静态方法只需要一个契约:

必须有一个主要的方法。

这里抽象构造函数和多重构造函数都不重要。

由于Java被设计为一种简单的语言,所以应用程序入口点被设计为使用一个简单的契约,而不是使用三个独立而脆弱的契约,这并不奇怪。

请注意:这个参数不是关于JVM或JRE内部的简单性。这个参数是关于用户的简单性。

在这里,完整的签名只能算作一份合同。

使用Java命令运行Java虚拟机(JVM)时,

java ClassName argument1 argument2 ...

当您执行您的应用程序时,您指定它的类名作为java命令的参数,如上所述

JVM尝试调用您指定的类的主方法

-在这一点上,类的对象还没有被创建。 将main声明为静态允许JVM在不创建的情况下调用main 类的实例。

让我们回到命令

ClassName是JVM的命令行参数,它告诉JVM要执行哪个类。在ClassName之后,您还可以指定一个字符串列表(由空格分隔)作为JVM将传递给应用程序的命令行参数。-这些参数可以用来指定运行应用程序的选项(例如文件名)-这就是为什么在main中有一个名为String[] args的参数

参考资料:Java™如何编程(早期对象),第十版