Home » Java » Why is the Java main method static?

Why is the Java main method static?

Posted by: admin November 2, 2017 Leave a comment


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

public static void main(String[] args){

Is there a reason for this method to be static?


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.


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

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 between 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.

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.

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.

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

So, long and short: the reason it is static is b/c that’s convenient. The reason it’s called ‘main’ is because 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 was important). 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.


The main() method in C++, C# and Java are static because they can then be invoked by the runtime engine without having to instantiate an instance of the parent class.


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)


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

... ...

{    /* 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) {
    goto leave;

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

... ...


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

A 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 matter.

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.


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.


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.


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.


What is the meaning of public static void main(String args[])?

  1. public is an access specifier meaning anyone can access/invoke it such as JVM(Java Virtual Machine.
  2. static allows main() to be called before an object of the class has been created. This is neccesary because main() is called by the JVM before any objects are made. Since it is static it can be directly invoked via the class.

    class demo {    
        private int length;
        private static int breadth;
        void output(){
        static void staticOutput(){
        public static  void main(String args[]){
            demo d1=new demo();
            d1.output(); // Note here output() function is not static so here
            // we need to create object
            staticOutput(); // Note here staticOutput() function is  static so here
            // we needn't to create object Similar is the case with main
            /* Although:
            demo.staticOutput();  Works fine
            d1.staticOutput();  Works fine */

    Similarly, we use static sometime for user defined methods so that we need not to make objects.

  3. void indicates that the main() method being declared
    does not return a value.

  4. String[] args specifies the only parameter in the main() method.

    args – a parameter which contains an array of objects of class type String.


Let me explain these things in a much simpler way:

public static void main(String args[])

All Java applications, except applets, start their execution from main().

The keyword public is an access modifier which allows the member to be called from outside the class.

static is used because it allows main() to be called without having to instantiate a particular instance of that class.

void indicates that main() does not return any value.


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 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 a main object.


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.


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?


When you execute the Java Virtual Machine (JVM) with the java command,

java ClassName argument1 argument2 ...

When you execute your application, you specify its class name as an argument to the java command, as above

the JVM attempts to invoke the main method of the class you specify

—at this point, no objects of the class have been created.

Declaring main as static allows the JVM to invoke main without creating
an instance of the class.

let’s back to the command

ClassName is a command-line argument to the JVM that tells it which class to execute. Following the ClassName, you can also specify a list of Strings (separated by spaces) as command-line arguments that the JVM will pass to your application. -Such arguments might be used to specify options (e.g., a filename) to run the application- this is why there is a parameter called String[] args in the main

References:Java™ How To Program (Early Objects), Tenth Edition


I think the keyword ‘static’ makes the main method a class method, and class methods have only one copy of it and can be shared by all, and also, it does not require an object for reference. So when the driver class is compiled the main method can be invoked. (I’m just in alphabet level of java, sorry if I’m wrong)


main() is static because; at that point in the application’s lifecycle, the application stack is procedural in nature due to there being no objects yet instantiated.

It’s a clean slate. Your application is running at this point, even without any objects being declared (remember, there’s procedural AND OO coding patterns). You, as the developer, turn the application into an object-oriented solution by creating instances of your objects and depending upon the code compiled within.

Object-oriented is great for millions of obvious reasons. However, gone are the days when most VB developers regularly used keywords like “goto” in their code. “goto” is a procedural command in VB that is replaced by its OO counterpart: method invocation.

You could also look at the static entry point (main) as pure liberty. Had Java been different enough to instantiate an object and present only that instance to you on run, you would have no choice BUT to write a procedural app. As unimaginable as it might sound for Java, it’s possible there are many scenarios which call for procedural approaches.

This is probably a very obscure reply. Remember, “class” is only a collection of inter-related code. “Instance” is an isolated, living and breathing autonomous generation of that class.


The protoype public static void main(String[]) is a convention defined in the JLS :

The method main must be declared public, static, and void. It must specify a formal parameter (§8.4.1) whose declared type is array of String.

In the JVM specification 5.2. Virtual Machine Start-up we can read:

The Java virtual machine starts up by creating an initial class, which is specified in an implementation-dependent manner, using the bootstrap class loader (§5.3.1). The Java virtual machine then links the initial class, initializes it, and invokes the public class method void main(String[]). The invocation of this method drives all further execution. Execution of the Java virtual machine instructions constituting the main method may cause linking (and consequently creation) of additional classes and interfaces, as well as invocation of additional methods.

Funny thing, in the JVM specification it’s not mention that the main method has to be static.
But the spec also says that the Java virtual machine perform 2 steps before :

Initialization of a class or interface consists of executing its class or interface initialization method.

In 2.9. Special Methods :

A class or interface initialization method is defined :

A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name <clinit>, takes no arguments, and is void.

And a class or interface initialization method is different from an instance initialization method defined as follow :

At the level of the Java virtual machine, every constructor written in the Java programming language (JLS §8.8) appears as an instance initialization method that has the special name <init>.

So the JVM initialize a class or interface initialization method and not an instance initialization method that is actually a constructor.
So they don’t need to mention that the main method has to be static in the JVM spec because it’s implied by the fact that no instance are created before calling the main method.


Recently, similar question has been posted at Programmers.SE

  • Why a static main method in Java and C#, rather than a constructor?

    Looking for a definitive answer from a primary or secondary source for why did (notably) Java and C# decide to have a static method as their entry point – rather than representing an application instance by an instance of an Application class, with the entry point being an appropriate constructor?

TL;DR part of the accepted answer is,

In Java, the reason of public static void main(String[] args) is that

  1. Gosling wanted
  2. the code written by someone experienced in C (not in Java)
  3. to be executed by someone used to running PostScript on NeWS


For C#, the reasoning is transitively similar so to speak. Language designers kept the program entry point syntax familiar for programmers coming from Java. As C# architect Anders Hejlsberg puts it,

…our approach with C# has simply been to offer an alternative… to Java programmers…


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.


The true entry point to any application is a static method. If the Java language supported an instance method as the “entry point”, then the runtime would need implement it internally as a static method which constructed an instance of the object followed by calling the instance method.

With that out of the way, I’ll examine the rationale for choosing a specific one of the following three options:

  1. A static void main() as we see it today.
  2. An instance method void main() called on a freshly constructed object.
  3. Using the constructor of a type as the entry point (e.g., if the entry class was called Program, then the execution would effectively consist of new Program()).


static void main()

  1. Calls the static constructor of the enclosing class.
  2. Calls the static method main().

void main()

  1. Calls the static constructor of the enclosing class.
  2. Constructs an instance of the enclosing class by effectively calling new ClassName().
  3. Calls the instance method main().

new ClassName()

  1. Calls the static constructor of the enclosing class.
  2. Constructs an instance of the class (then does nothing with it and simply returns).


I’ll go in reverse order for this one.

Keep in mind that one of the design goals of Java was to emphasize (require when possible) good object-oriented programming practices. In this context, the constructor of an object initializes the object, but should not be responsible for the object’s behavior. Therefore, a specification that gave an entry point of new ClassName() would confuse the situation for new Java developers by forcing an exception to the design of an “ideal” constructor on every application.

By making main() an instance method, the above problem is certainly solved. However, it creates complexity by requiring the specification to list the signature of the entry class’s constructor as well as the signature of the main() method.

In summary, specifying a static void main() creates a specification with the least complexity while adhering to the principle of placing behavior into methods. Considering how straightforward it is to implement a main() method which itself constructs an instance of a class and calls an instance method, there is no real advantage to specifying main() as an instance method.


The public keyword is an access modifier, which allows the programmer to control
the visibility of class members. When a class member is preceded by public, then that
member may be accessed by code outside the class in which it is declared.

The opposite of public is private, which prevents a member from being used by code defined outside of its class.

In this case, main() must be declared as public, since it must be called
by code outside of its class when the program is started.

The keyword static allows
main() to be called without having to instantiate a particular instance of the class. This is necessary since main() is called by the Java interpreter before any objects are made.

The keyword void simply tells the compiler that main() does not return a value.


static – When the JVM makes a call to the main method there is no object that exists for the class being called therefore it has to have static method to allow invocation from class.


Static methods don’t require any object. It runs directly so main runs directly.


The static key word in the main method is used because there isn’t any instantiation that take place in the main method.
But object is constructed rather than invocation as a result we use the static key word in the main method.
In jvm context memory is created when class loads into it.And all static members are present in that memory. if we make the main static now it will be in memory and can be accessible to jvm (class.main(..)) so we can call the main method with out need of even need for heap been created.


It is just a convention as we can see here:

The method must be declared public and static, it must not return any
value, and it must accept a String array as a parameter. By default,
the first non-option argument is the name of the class to be invoked.
A fully-qualified class name should be used. If the -jar option is
specified, the first non-option argument is the name of a JAR archive
containing class and resource files for the application, with the
startup class indicated by the Main-Class manifest header.



The public static void keywords mean the Java virtual machine (JVM) interpreter can call the program’s main method to start the program (public) without creating an instance of the class (static), and the program does not return data to the Java VM interpreter (void) when it ends.

Essentials, Part 1, Lesson 2: Building Applications


I don’t know if the JVM calls main method before the objects are instantiated… But there is far more powerful reason why the main() method is static… When JVM calls the main method of the class (say Person)… it invokes it by “Person.main()” …. You see, the JVM invokes it by the class name. That is why the main() method is supposed to be static and public, so that it can be accessed by the JVM.

Hope it helped… 🙂 … If it did, let me know by commenting..! 😀


Basically we make those DATA MEMBERS and MEMBER FUNCTIONS as STATIC which are not performing any task related to an object. And in case of main method, we are making it as an STATIC because it is nothing to do with object, as the main method always run whether we are creating an object or not.


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:


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.


there is the simple reason behind it that is because object is not required to call static method , if It were non-static method, java virtual machine creates object first then call main() method that will lead to the problem of extra memory allocation.