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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/146576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:54:14  来源:igfitidea点击:

Why is the Java main method static?

javastaticmain

提问by Alotor

The method signature of a Java main()method is:

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

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

Is there a reason for this method to be static?

这种方法是否有理由是静态的?

采纳答案by Jacob Krall

The method is static because otherwise there would be ambiguity: which constructor should be called? Especially if your class looks like this:

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

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

Should the JVM call new JavaClass(int)? What should it pass for x?

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

If not, should the JVM instantiate JavaClasswithout running any constructor method? I think it shouldn't, because that will special-case your entire class - sometimes you have an instance that hasn't been initialized, and you have to check for it in every method that could be called.

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

There are just too many edge cases and ambiguities for it to make sense for the JVM to have to instantiate a class before the entry point is called. That's why mainis static.

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

I have no idea why mainis always marked publicthough.

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

回答by Logan

It's just a convention, but probably more convenient than the alternative. With a static main, all you need to know to invoke a Java program is the name and location of a class. If it weren't static, you'd also have to know how to instantiate that class, or require that the class have an empty constructor.

这只是一个约定,但可能比替代方案更方便。对于静态 main,调用 Java 程序所需知道的只是类的名称和位置。如果它不是静态的,您还必须知道如何实例化该类,或者要求该类具有空构造函数。

回答by Noah Goodrich

The main()method in C++, C#and Javaare static
Because they can then be invoked by the runtime engine withouthaving to instantiate any objects then the code in the body of main()will do the rest.

main()在方法C++C#Java是静态
因为他们然后可以由运行时引擎调用而不不必实例的任何对象,则代码在身体的main()将完成剩下的。

回答by BlackWasp

Before the main method is called, no objects are instantiated. Having the static keyword means the method can be called without creating any objects first.

在调用 main 方法之前,不会实例化任何对象。拥有 static 关键字意味着可以在不先创建任何对象的情况下调用该方法。

回答by PhiLho

Because otherwise, it would need an instance of the object to be executed. But it must be called from scratch, without constructing the object first, since it is usually the task of the main() function (bootstrap), to parse the arguments and construct the object, usually by using these arguments/program parameters.

因为否则,它将需要一个对象的实例来执行。但是它必须从头开始调用,而不是先构造对象,因为它通常是 main() 函数(引导程序)的任务,解析参数并构造对象,通常是通过使用这些参数/程序参数。

回答by Hank

If it wasn't, which constructor should be used if there are more than one?

如果不是,如果有多个构造函数,应该使用哪个构造函数?

There is more information on the initialization and execution of Java programs available in the Java Language Specification.

Java 语言规范中有更多关于 Java 程序的初始化和执行的信息。

回答by Tom Hawtin - tackline

Applets, midlets, servlets and beans of various kinds are constructed and then have lifecycle methods called on them. Invoking main is all that is ever done to the main class, so there is no need for a state to be held in an object that is called multiple times. It's quite normal to pin main on another class (although not a great idea), which would get in the way of using the class to create the main object.

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

回答by Tom

It is just a convention. The JVM could certainly deal with non-static main methods if that would have been the convention. After all, you can define a static initializer on your class, and instantiate a zillion objects before ever getting to your main() method.

这只是一个约定。如果这是惯例,JVM 当然可以处理非静态 main 方法。毕竟,您可以在您的类上定义一个静态初始化程序,并在使用 main() 方法之前实例化无数个对象。

回答by micro

If the main method would not be static, you would need to create an object of your main class from outside the program. How would you want to do that?

如果 main 方法不是静态的,则需要从程序外部创建主类的对象。你想怎么做?

回答by Kevin Day

This is just convention. In fact, even the name main(), and the arguments passed in are purely convention.

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

When you run java.exe (or javaw.exe on Windows), what is really happening is a couple of Java Native Interface (JNI) calls. These calls load the DLL that is really the JVM (that's right - java.exe is NOT the JVM). JNI is the tool that we use when we have to bridge the virtual machine world, and the world of C, C++, etc... The reverse is also true - it is not possible (at least to my knowledge) to actually get a JVM running without using JNI.

当您运行 java.exe(或 Windows 上的 javaw.exe)时,真正发生的是几个 Java Native Interface (JNI) 调用。这些调用加载了真正是 JVM 的 DLL(没错 - java.exe 不是 JVM)。JNI 是我们必须在虚拟机世界和 C、C++ 等世界之间架起桥梁时使用的工具......反过来也是如此——实际上不可能(至少据我所知)获得一个JVM 在不使用 JNI 的情况下运行。

Basically, java.exe is a super simple C application that parses the command line, creates a new String array in the JVM to hold those arguments, parses out the class name that you specified as containing main(), uses JNI calls to find the main() method itself, then invokes the main() method, passing in the newly created string array as a parameter. This is very, very much like what you do when you use reflection from Java - it just uses confusingly named native function calls instead.

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

It would be perfectly legal for you to write your own version of java.exe (the source is distributed with the JDK) and have it do something entirely different. In fact, that's exactly what we do with all of our Java-based apps.

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

Each of our Java apps has its own launcher. We primarily do this so we get our own icon and process name, but it has come in handy in other situations where we want to do something besides the regular main() call to get things going (For example, in one case we are doing COM interoperability, and we actually pass a COM handle into main() instead of a string array).

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

So, long and short: the reason it is static is b/c that's convenient. The reason it's called 'main' is that it had to be something, and main() is what they did in the old days of C (and in those days, the name of the function wasimportant). I suppose that java.exe could have allowed you to just specify a fully qualified main method name, instead of just the class (java com.mycompany.Foo.someSpecialMain) - but that just makes it harder on IDEs to auto-detect the 'launchable' classes in a project.

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