16

I was recently asked in an exam if public static void main(String arg[]) format of main method was fixed? Can we change it? Can we use main without any of public, static or void? If not, why is it not hard coded that main(String arg[]) would stand for public static void main(String arg[]) always?

Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
amar
  • 4,285
  • 8
  • 40
  • 52

9 Answers9

26

The signature of the main method is specified in the Java Language Specifications section 12.1.4 and clearly states:

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.

  • it must be public otherwise it would not be possible to call it
  • it must be static since you have no way to instantiate an object before calling it
  • the list of String arguments is there to allow to pass parameters when executing a Java program from the command line. It would have been possible to define it without arguments but is more practical like that (and similar to other languages)
  • the return type is void since it does not make sense to have anything else: a Java program can terminate before reaching the end of the main method (e.g., by calling System.exit())

The method signature can therefore be:

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

note that the varargs version (...) is only valid from Java 5

As the Java language allows the brackets [] to be positioned after the type or the variable (the first is generally preferred),

public static void main( String args[] ) // valid but usually non recommended

is also valid

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Matteo
  • 14,696
  • 9
  • 68
  • 106
  • You can easily create a new launcher that will do it in a different way, the method doesn't have to be public (the JNI interface allows you to call **any** method) and it doesn't have to be static, the JNI interface again can create **any object** by calling it's constructor and then call the instance method. – Maurício Linhares Apr 05 '12 at 12:53
  • 3
    @MaurícioLinhares I perfectly know that I could call whatever I want but there is no guarantee that it will work. A JVM (there are other JVM also not from Oracle) are only forced to follow the specs. They could simply generate an error and tell you "no way, not standard even if technically possible". A specification is called specification for a reason. – Matteo Apr 05 '12 at 12:56
  • **there is no guarantee that it will work** ? What do you mean by that? That my personal launcher won't work because the spec says otherwise? Any launcher **will work** provided the class being launched meets it's criteria, please check the other answers and the source code examples. – Maurício Linhares Apr 05 '12 at 12:58
  • Yes, a JVM not from Oracle (or a new version) could just tell you that what you wrote is not OK with the language specs and it would be OK. – Matteo Apr 05 '12 at 13:01
  • That's not a JVM pal, it's a program that **calls** the JVM. What kind of magic do you think is employed to make Tomcat run as a service on Windows? **BANG**, a custom launcher, just like the one I linked. In case you don't know, there's a lot of people out there who **need** this interface and use it in many different cases (like the PostgreSQL guys with their Java stored procedures). – Maurício Linhares Apr 05 '12 at 13:03
  • I don't care about what someone does with JNI, I perfectly know that you can do whatever you want. But we are answering to a question about the Java language not on how launch stuff on Windows. If the custom launcher is in Java than it needs a default main, if it's, let's say, in C than it not relevant to the question. The OP did not ask how can I execute Bytecode from another language, he asked what he can do in Java. – Matteo Apr 05 '12 at 13:07
  • what about public static void main (String args[]) – abhi May 20 '13 at 04:48
  • 1
    @abhi In Java you you can position the brackets after the type or the variable: both are allowed (although the first is generally preferred). – Matteo May 20 '13 at 08:32
  • So was there an old version when this was *not* in the specification? I've never used Java and I'm taking this horrible course with a project that directs the student to copy this tiny little app, but it *won't compile*, because **"Error: Main method not found in class `CLASSNAME`, please define the main method as: public static void main(String[] args)"**. I know the course materials are ridiculously poorly maintained, and I'm wondering if this may be another symptom of that.... – Owen_AR Jun 26 '13 at 19:11
  • @Owen_R No the main method was defined like that since the first version (but for the ... version). You should create your own question and show us the the code. – Matteo Jun 30 '13 at 15:37
  • @Matteo Yeah, it seemed unlikely. Anyway thanks, but I figured it out. (Basically, they just did a really bad job making a clear distinction between application and applet.) – Owen_AR Jun 30 '13 at 18:56
  • This is finally changing in 2023 with JEP 445, that appears as a preview feature in JDK 21. [JEP 445](https://openjdk.org/jeps/445) has 2 parts, first you can simply write the method _main_ withot _public static_, second you don't need a class: `void main() { System.out.println("Hello, World!"); }` – PragmaCoder Jun 06 '23 at 05:36
2

If you look into JDK source code (jdk-src\j2se\src\share\bin\java.c):

/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                   "([Ljava/lang/String;)V");
...
{    /* Make sure the main method is public */
...
mods = (*env)->CallIntMethod(env, obj, mid);
if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
    message = "Main method not public.";
    messageDest = JNI_TRUE;
    goto leave;
...

It becomes very clear that it must have only this signature.

kan
  • 28,279
  • 7
  • 71
  • 101
2

Public is a kind of access specifier due to which we can access it from outside the class. Since main is the function that acts as an execution point. Main function is called by the JVM which is outside the class so it must be declared as public.

Static is a kind of keyword used in java to specify that there is no need to create any instance of it. As we know main method also reside inside a class and to access the particular function of a class from outside the class (In this case from JVM), an instance of that particular class is needed, so to avoid these we simply put static to make access main method outside of class.

Void is the return type since other return type in main method is meaningless.

String is a pre-defined class name in java. And args [] is a variable of array types. It’s a variable name of String type object. So we can also change the name of args []. String class and its object can be passed in a running program as an argument to pass information to the main method from command line.

Ashwin J
  • 662
  • 7
  • 12
0

The main method must be public so it can be found by the JVM when the class is loaded. Similarly, it must be static so that it can be called after loading the class, without having to create an instance of it. All methods must have a return type, which in this case is void.

Thorn G
  • 12,620
  • 2
  • 44
  • 56
0

I cannot answer for the arguments of the method but it must be public because the jvm must be able to access the function and it must be static because the jvm does not know how to create an instance of your class.

This post provides a good detailed answer about the reasoning for static: Why is the Java main method static?

This post provides a good answer for why main is void: Why is main() in java void?

Community
  • 1
  • 1
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
0

If not, why is it not hard coded that main(String arg[]) would stand for public static void main(String arg[]) always?

You can have methods called "main" with any signature and access you like. The special rules only apply to the method you want the JVM to call to start a program.

public class Test {
  public static void main(String[] args) {
    StrangeMain m = new StrangeMain();
    System.out.println(m.main());
    System.out.println(m.main(new String[]{"aaa","bbb"}));
  }
}

class StrangeMain{
  protected String main(){
    return "xyzzy";
  }
  protected String main(String[] arg){
    return arg[0];
  }
}

compiles, runs, and outputs:

xyzzy
aaa
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
0
             Public static void main(String [] ar)

To understand this we need to know the syntax of method and the array.

Syntax of method is :

return type methodName

so the main method is written along with void which is return type.

Syntax of Array:

datatype [] arrayName

the square braces indicates whether it is the of dimension array .Since we have one pair of square braces it is one dimension array.

The meaning of words in the main method:

Public: Public is the access specifier it is intended for the purpose of the JVM to execute the main method from any location.

Static : Static is a modifier.The main method must be declared as static so that the JVM can access the main method directly by using the class name.

When we execute a java program we use the class name so when we write static it will help the JVM to access the main method.

If we remove static then it becomes instance method,to access an instance method we should create and object and then invoke the method using the object reference.

void : Void is the return type of main method. The Caller of the main method is JVM and the JVM does not expect any value from the main method and there fore the main method should not return any value.This is the reason for specifying Void.

main : Main is the method name and it is fixed as per the Java coding conventions.

String[]: It is used for storing the command line arguments.The name of the array can be any valid Java identifier.

So after String[] we can give name as any valid java identifier it can be 'ar' or it can be 'args'.

Bharath M
  • 21
  • 1
-2

You can change it if you create a new loader for your app. The public static void main( String args[] ) format is just the default solution people working on the JVM found to call your Java programs, so that there is a definite way to do it.

The real implementation we have today just uses the JNI interface to call the public static void main (String args[]) method by using this function, so you could easily write exactly the same code if you wanted using JNI and have a different method to load your app.

Here's an example in code that was taken from this page.

Here's the current linux launcher program, the method lookup starts here.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
  • You sure? My hotspot source code has it hardcoded: `(*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");` – Voo Apr 05 '12 at 12:41
  • No it's defined in the language specs and it is only guaranteed to work if implemented as defined. Anything not following the specs is not guaranteed to work. http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.4 – Matteo Apr 05 '12 at 12:45
  • Of course it is, check the launcher source code. https://gist.github.com/2310831#L465 – Maurício Linhares Apr 05 '12 at 12:50
  • @MaurícioLinhares "It works now" does not mean "is correct". There is a specification and it is the only reference. A JVM implementation must adhere to the specs not to what works with another version. Standards are made for a reason. – Matteo Apr 05 '12 at 12:52
  • 1
    @Matteo we **are not** talking about the spec here, we're talking about the possibility of **having a different launcher that can call a different method** and you're just repeating it is impossible while it isn't. – Maurício Linhares Apr 05 '12 at 12:55
  • @Maurício By that definition, Java also supports out parameters because we can write a different compiler and JVM.. well you see where that's going :) If the JLS demands something, any implementation that doesn't follow it isn't implementing java but some frankenjava. – Voo Apr 05 '12 at 12:58
  • Hum, no, it wouldn't be part of the language and it wouldn't be **Java**, so you can't do that and call it Java. But you can use the JNI interface to boot your programs any way you like since it would use the currently published JNI APIs and would not have to change any of the Java's source code. Also, **many tools** rely on this fact, as the Win4j launcher that runs Java programs in the background. – Maurício Linhares Apr 05 '12 at 13:00
  • 1
    @MaurícioLinhares of course we are speaking about the specs. The question asks about Java. Java is precisely defined language and that's it. – Matteo Apr 05 '12 at 13:03
-2
  • public-main() method must be used by any one of the outside the class as well as inside the class so its public

  • static-static is necessary bcoz in java if we define class than we define object for that class and than and only than we can use that class..but instead of this we directly use by write the word static

  • void-for main() cant return any value like int or char main()-main is the function or method which we can use for accessing the future of java String-in java all we write consider as a string args-arguments

Grisha Weintraub
  • 7,803
  • 1
  • 25
  • 45