为什么main方法在java中是静态的

时间:2010-07-05 17:24:30

标签: java static main

我听过有人说“如果main不是静态的,那么JVM可以创建一个对象 包含main的类,并通过对象调用main 但问题是JVM如何知道在重载构造函数的情况下调用哪个构造函数,或者即使只有一个参数化的构造函数,然后传递什么。“

这是正确的理由吗?
因为如何在不进入主函数的情况下创建类的对象?
请就此发表意见。如果这不是正确的理由,那么正确的原因是什么?

10 个答案:

答案 0 :(得分:18)

这只是一个惯例。 Java语言设计者可以很容易地决定你必须指定一个要实例化的类,使其构造函数成为主要方法。但是调用静态方法同样有效,并且不需要首先实例化类。

此外,如果类具有超类,则可以通过更改超类来更改程序启动的行为(因为必须在子类之前调用​​超类构造函数),这可能是无意的。静态方法没有这个问题。

主要方法是静态的,因为它使事情变得更简单,但是如果他们想让它变得更复杂,那么它们就可以了。

答案 1 :(得分:5)

  

“这个原因是否正确?”

在某种程度上,虽然从来没有像那样具体解释过。

我们可以让约定也用String...args来调用构造函数,这意味着你至少需要一个对象来运行,但(可能)设计者认为不需要它。

例如,这样的事情没有技术障碍:

 class Hello {
       public void main(String...args){
           System.out.println("Hello, world");

       }
 }

事实上,如果你没有指定一个,那么Java会为你创建一个no-arg构造函数,如果这个类包含一个main方法,那么创建一个var args构造函数也很容易。引擎盖下面的代码:

 class Hello {
      // created by the compiler
      public Hello(){}
      public Hello( String ... args ) {
          this();
          main( args );
      }
      // end of code created by the compiler
      public void main( String ... args ) {
           System.out.println("Hello, world!");
      }
  }

但这会产生不需要的代码,以及在这种情况下不会做任何事情的额外分配对象;两个构造函数(而不是一个)等。最后它看起来就像是太多的魔法。

由语言设计师决定。在这种情况下,他们可能认为不这样做会更简单,只是验证调用的类是否具有名为public static void main( String [] args )的方法的特殊签名

顺便说一句,你可以在Java without main method中使用Hello! world程序,但它会抛出java.lang.NoSuchMethodError: main

public class WithoutMain {
    static {
        System.out.println("Look ma, no main!!");
        System.exit(0);
    }
}

$ java WithoutMain
Look ma, no main!!

我知道这不是另类,但是,有趣的不是吗?

答案 2 :(得分:2)

  

我听过有人说“如果main不是静态的,那么JVM可以创建一个包含main的类对象,并通过对象调用main。

事实并非如此。至少,JLS中没有指定。

  

但问题是JVM如何知道在重载构造函数的情况下调用哪个构造函数,或者即使只有一个参数化的构造函数,然后传递什么。“

如果确实如此,我只是希望它调用(隐式)默认的no-arg构造函数。

另见:

答案 3 :(得分:2)

static是一个关键字,当它在main方法之前应用时,JVM将假设这是执行的起点。那么JVM是这样想的吗? 给予JVM责任的java软人员通过main()方法输入指定的类 EX: 假设有两个类A和B, 其中B延伸A, 这里按照java,对于每个类,应该创建一个对象来访问该类中的变量和方法,这里在类B中写入静态main()方法,静态是单词,无论程序执行开始如何...将被分配程序执行前该关键字的内存。

答案 4 :(得分:1)

因为它可能有主要方法。而且因为主要对象不需要是一个对象。如果是,您需要实例化一个。

如果您自己使用jvm.dll,并且只需创建一个对象并调用它,那么您不需要main函数。

然而,通过这种方式,可以进行非面向对象的编程,仅适用于那些出于某种原因需要它的人。 :)

答案 5 :(得分:1)

main是静态的,因此您的代码可以执行而无需先实例化一个类。也许你甚至不想创建一个类,或者创建类很慢,你想首先打印出一个“Loading ...”文本,或者你有多个构造函数等...有很多原因没有在命令执行开始之前强制用户创建一个类。

如果静态创建对象,仍然可以在执行main()之前创建对象。

答案 6 :(得分:1)

是的,在JVM上运行的其他语言创建对象或模块(也是对象)并运行它们。例如,Fortress语言“Hello world”看起来像

Component HelloWorld
Export Executable
run(args) = print "Hello, world!"
end

或者,没有args:

Component HelloWorld
Export Executable
run() = print "Hello, world!"
end

Java比纯OO语言更实用,具有静态方法和字段以及原始类型。它的静态主方法更接近C的主要功能。你不得不问戈斯林他为什么选择这个惯例。

启动JVM的代码非常简单 - 这个示例创建一个JVM,创建一个对象并使用命令行参数调用其run方法 - 使启动函数(new main.HelloWorld()).run(args)而不是{{ 1}}:

main.HelloWorld.main(args)

答案 7 :(得分:1)

无需创建对象来调用静态方法。所以jvm不需要分配额外的内存来创建main的obj然后调用它。

答案 8 :(得分:0)

  

但问题是JVM如何知道在重载构造函数的情况下调用哪个构造函数,或者即使只有一个参数化的构造函数,然后传递什么。“

我也这么认为。我不使用Java。我用C ++。如果您不自己编写构造函数,则会隐式提供默认的无参数构造函数和复制构造函数。但是当你自己编写构造函数时,编译器不会提供构造函数。我认为这个理论也得到了Java的遵守。

所以在Class中它不能保证它不会有一个Constructor。还限制一个类具有用户定义的构造函数是一个坏主意。但是如果系统允许你编写自己的构造函数,那么即使不能保证它将是无参数构造函数。所以如果它是一个参数化的构造函数它不知道要发送什么参数。

所以我认为这是静态主要功能背后的实际原因。

答案 9 :(得分:0)

在java main方法中是静态的,Java虚拟机可以调用它而无需创建包含main方法的任何类实例。如果main方法没有声明为静态,那么JVM必须创建主类的实例,并且因为构造函数可以重载并且可以有参数,所以JVM在Java中找不到主方法也没有任何确定和一致的方法。