开发者

Why main method is static in java [duplicate]

开发者 https://www.devze.com 2023-01-05 14:46 出处:网络
This question already has answers here: 开发者_如何学运维 Why is the Java main method static? (37 answers)
This question already has answers here: 开发者_如何学运维 Why is the Java main method static? (37 answers) Closed 5 years ago.

I have heard some people saying " if main is not static then JVM could create an object of class containing main and call that main through object.

But the problem is how JVM knows which constructor to call in case of overloaded constructors or even if there is only one paramaterized constructor, then what to pass."

Is that the correct reason?

Because how can object of class be created without entering into main function?

Please give your views on this. If that is not the right reason, then what's the correct reason?


It's just a convention. The Java language designers could have easily decided that you must designate a class to be instantiated, making its constructor the main method. But calling a static method is just as effective and doesn't require a class to be instantiated first.

Also, if the class has a superclass, you could alter the behavior of program startup by changing a superclass (since superclass constructors must be called before subclasses), perhaps unintentionally. Static methods don't have this problem.

The main method is static because it keeps things simpler, but if they wanted to make it more complicated, they could have.


"Is this reason correct?"

It is at some degree, although it was never specifically explained like that.

We could have the convention to also invoke the constructor with String...args , that would imply you need at least an object to run, but ( probably ) the designers thought that wasn't needed.

For instance, there is no technical impediment to have something like this:

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

       }
 }

As a metter of fact, Java creates a no-arg constructor for you if you don't specify one, it would be very easy to include a var args constructor too, if the class contained a main method, and create under the hood the following code:

 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!");
      }
  }

But that would create unneeded code, and extra allocated object that in this case wouldn't do anything; two constructors ( instead of one ) etc. At the end it would look like just too much magic.

Is up to the language designers. In this case they probably thought it would be simpler not to do it and just validate if the invoked class had the special signature of a method called public static void main( String [] args )

BTW you can have a Hello! world program in Java without main method, but it throws java.lang.NoSuchMethodError: main

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

$ java WithoutMain
Look ma, no main!!

I know it is not an alternative, but yet, it is interesting isn't?


I have heard some people saying " if main is not static then JVM could create an object of class containing main and call that main through object.

This is not true. At least, this is nowhere specified in the JLS.

But the problem is how JVM knows which constructor to call in case of overloaded constructors or even if there is only one paramaterized constructor, then what to pass."

If it were true, I'd just expect it to invoke the (implicit) default no-arg constructor.

See also:

  • JLS - Invoke main method


static is a keyword,when it is applied before main method,JVM will be assumes that this is the starting point of execution.so y JVM think like that? java soft people given to JVM as responsibility to enter the specified class through main() method EX: suppose there are two classes A nd B, where B extends A, here as per java,for every class a object should be created for accessing variables and methods in that class,here in class B static main() method is wrote, static is word as says irrespective of program excution starts..it will be allocated memory for that keyword before Program excution.


Because its possible to have main methods. And because the main object does not need to be an object. If it was, you would need to instantiate one.

And you don't need a main function, if you use the jvm.dll for yourself, and just create an object and call this.

However, in this way it is possible to do non-object-oriented programming, just for those who need this for some reason. :)


main is static so your code can execute without having to instantiate a class first. Maybe you don't even want to create a class, or maybe creating the class is slow and you want to print out a "Loading..." text first, or you have multiple constructors, etc... there are many reasons not to force the user to create a class before command execution can begin.

You can still create objects before main() is executed if you create them statically.


Yes, other languages which run on the JVM create objects or modules (which are also objects) and run them. For example, the Fortress language 'Hello world' looks like

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

or, without the args:

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

Java is a bit more pragmatic than a pure OO language, having static methods and fields and primitive types. Its static main method is closer to C's main function. You would have to ask Gosling as to why he chose that convention.

The code to launch the JVM is fairly simple - this example creates a JVM, creates an object and calls its run method with the command line arguments - making the startup function (new main.HelloWorld()).run(args) rather than main.HelloWorld.main(args):

#include <stdio.h>
#include <jni.h>

JNIEnv* create_vm() {
    JavaVM* jvm;
    JNIEnv* env;
    JavaVMInitArgs args;
    JavaVMOption options[1];

    args.version = JNI_VERSION_1_2;
    args.nOptions = 1;

    options[0].optionString = "-Djava.class.path=C:\\java_main\\classes";
    args.options = options;
    args.ignoreUnrecognized = JNI_TRUE;

    JNI_CreateJavaVM(&jvm, (void **)&env, &args);

    return env;
}

int invoke_class(JNIEnv* env, int argc, char **argv) {
    jclass helloWorldClass;

    helloWorldClass = env->FindClass("main/HelloWorld");

    if (helloWorldClass == 0)
        return 1;

    jmethodID constructorMethod = env->GetMethodID(helloWorldClass, "<init>", "()V");

    jobject object = env->NewObject(helloWorldClass, constructorMethod);

    if (object == 0)
        return 1;

    jobjectArray applicationArgs = env->NewObjectArray(argc, env->FindClass("java/lang/String"), NULL);

    for (int index = 0; index < argc; ++index) {
        jstring arg = env->NewStringUTF(argv[index]);
        env->SetObjectArrayElement(applicationArgs, index, arg);
    }

    jmethodID runMethod = env->GetMethodID(helloWorldClass, "run", "([Ljava/lang/String;)V");

    env->CallVoidMethod(object, runMethod, applicationArgs);

    return 0;
}

int main(int argc, char **argv) {
    JNIEnv* env = create_vm();

    return invoke_class( env, argc, argv );
}


there is no need to create an object to call a static method. So there is no need for jvm to allocate extra memory to create obj of main and then call it.


But the problem is how JVM knows which constructor to call in case of overloaded constructors or even if there is only one paramaterized constructor, then what to pass."

I do also think so. I dont use Java. I use C++. If you dont write a constructor by yourself a default no argument constructor and a copy constructor is implicitly provided to you. But when you write a constructor by yourself then no constructor is provided by the Compiler. I think this theory is obeyed by Java too.

So in a Class its not guaranteed that it will not have a Constructor. also restricting a Class from having an user defined constructor is a bad idea. But If the system lets you to write your own constructor then even there is no guarantee that it will be no-argument constructor. so if it is a parameterized constructor It doesn't know what parameters to send.

So I think thats the actual reason behind static Main function.

0

精彩评论

暂无评论...
验证码 换一张
取 消