tags:

views:

327

answers:

8

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?

+1  A: 

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. :)

Daniel
+2  A: 

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:

BalusC
I would expect it to use the this(String... args) constructor.
Daniel
Ok..I just want to ask is it possible in any case that JVM could create an object of class containing main?If object can be created, is it possible to call main through that?Please give an example.
Happy Mittal
(almost) anything is possible. But the JVM does not currently do that, and the jvm/java spec doesn't say it should.
nos
No, it doesn't. You need to do it **yourself** (inside the `main()` method).
BalusC
-1 saying that the JVM doesn't do something that way does not preclude the possibility that some other implementation could be created. For example, Fortress runs in exactly the manner described.
Pete Kirkham
@Pete: I was giving an answer based on JLS. Blaming me because it's technically not impossible makes honestly no sense :)
BalusC
'technically not impossible' means technically possible, as the example code I give shows.
Pete Kirkham
@Pete: please point where I said that it's technically impossible. It's truly technically possible :) Else other languages-on-top-of-JVM like Clojure/Scala/Etc can't possibly exist. Your answer just demonstrates exactly that by going around JLS and manipulating the JVM. You're taking my answer a bit too narrow. Too bad, else I'd be eager to upvote your answer since that's simply a nice demo, even though benzado's answer nails it better down than our answers.
BalusC
I quoted the comment above mine directly. Your answer implies that the JVM is bound by the JLS. This is not true.
Pete Kirkham
+1  A: 

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.

EboMike
A: 

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.

+14  A: 

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.

benzado
Java is modelled on C, and the Java concept of "main" is very close to the C concept of "main".
Thorbjørn Ravn Andersen
+1  A: 

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 );
}
Pete Kirkham
+2  A: 

"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?

OscarRyz
A: 

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.

M.venkat shekhar