Why is the Java main method static?

前端 未结 30 2174
离开以前
离开以前 2020-11-22 01:41

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

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

Is the

相关标签:
30条回答
  • 2020-11-22 01:53

    Let's simply pretend, that static would not be required as the application entry point.

    An application class would then look like this:

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

    The distinction between constructor code and main method is necessary because in OO speak a constructor shall only make sure, that an instance is initialized properly. After initialization, the instance can be used for the intended "service". Putting the complete application code into the constructor would spoil that.

    So this approach would force three different contracts upon the application:

    • There must be a default constructor. Otherwise, the JVM would not know which constructor to call and what parameters should be provided.
    • There must be a main method1. Ok, this is not surprising.
    • The class must not be abstract. Otherwise, the JVM could not instantiate it.

    The static approach on the other hand only requires one contract:

    • There must be a main method1.

    Here neither abstract nor multiple constructors matters.

    Since Java was designed to be a simple language for the user it is not surprising that also the application entry point has been designed in a simple way using one contract and not in a complex way using three independent and brittle contracts.

    Please note: This argument is not about simplicity inside the JVM or inside the JRE. This argument is about simplicity for the user.


    1Here the complete signature counts as only one contract.

    0 讨论(0)
  • 2020-11-22 01:56

    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?

    If not, should the JVM instantiate JavaClass without 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.

    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 main is static.

    I have no idea why main is always marked public though.

    0 讨论(0)
  • 2020-11-22 01:56

    Why public static void main(String[] args) ?

    This is how Java Language is designed and Java Virtual Machine is designed and written.

    Oracle Java Language Specification

    Check out Chapter 12 Execution - Section 12.1.4 Invoke Test.main:

    Finally, after completion of the initialization for class Test (during which other consequential loading, linking, and initializing may have occurred), the method main of Test is invoked.

    The method main must be declared public, static, and void. It must accept a single argument that is an array of strings. This method can be declared as either

    public static void main(String[] args)
    

    or

    public static void main(String... args)
    

    Oracle Java Virtual Machine Specification

    Check out Chapter 2 Java Programming Language Concepts - Section 2.17 Execution:

    The Java virtual machine starts execution by invoking the method main of some specified class and passing it a single argument, which is an array of strings. This causes the specified class to be loaded (§2.17.2), linked (§2.17.3) to other types that it uses, and initialized (§2.17.4). The method main must be declared public, static, and void.

    Oracle OpenJDK Source

    Download and extract the source jar and see how JVM is written, check out ../launcher/java.c, which contains native C code behind command java [-options] class [args...]:

    /*
     * Get the application's main class.
     * ... ...
     */
    if (jarfile != 0) {
        mainClassName = GetMainClassName(env, jarfile);
    
    ... ...
    
        mainClass = LoadClass(env, classname);
        if(mainClass == NULL) { /* exception occured */
    
    ... ...
    
    /* Get the application's main method */
    mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                                       "([Ljava/lang/String;)V");
    
    ... ...
    
    {    /* Make sure the main method is public */
        jint mods;
        jmethodID mid;
        jobject obj = (*env)->ToReflectedMethod(env, mainClass,
                                                mainID, JNI_TRUE);
    
    ... ...
    
    /* Build argument array */
    mainArgs = NewPlatformStringArray(env, argv, argc);
    if (mainArgs == NULL) {
        ReportExceptionDescription(env);
        goto leave;
    }
    
    /* Invoke main method. */
    (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
    
    ... ...
    
    0 讨论(0)
  • 2020-11-22 01:56

    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.

    0 讨论(0)
  • 2020-11-22 01:56

    Any method declared as static in Java belongs to the class itself . Again static method of a particular class can be accessed only by referring to the class like Class_name.method_name();

    So a class need not to be instantiated before accessing a static method.

    So the main() method is declared as static so that it can be accessed without creating an object of that class.

    Since we save the program with the name of the class where the main method is present( or from where the program should begin its execution, applicable for classes without a main() method()(Advanced Level)). So by the above mentioned way:

    Class_name.method_name();
    

    the main method can be accessed.

    In brief when the program is compiled it searches for the main() method having String arguments like: main(String args[]) in the class mentioned(i.e. by the name of the program), and since at the the beginning it has no scope to instantiate that class, so the main() method is declared as static.

    0 讨论(0)
  • 2020-11-22 01:58

    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.

    0 讨论(0)
提交回复
热议问题