22

Although the return type is not a part of a method's signature, JVM looks for exact declaration as

 public static void main(String[] args)

My assumption is that since method signature does not have "return type" included, I must be allowed to change the return type.

But if I change it to public static int main(String[] args) and return a value lets say 0, JVM is not able to execute the program and exits with an error

Error: Main method must return a value of type void in class TestData, please 
define the main method as:
   public static void main(String[] args)

Why do Java Specifications want the main method to be void only? Why is this restriction, when return type is not a part of method signature?

This question is different than Why is main() in java void? : this question is closed as it is opinion based, while I am looking for the code places/ processes from where JVM is invoking this method, and what are the limitations which are forcing them to keep this method as void. What are the design decisions they have taken (and the reasoning behind), and where is it documented.

I am looking for facts, so as to know the reason why is it done so. Please don't mark it duplicate without going through the details of the question.

PS: exit, is another thing. I am more concerned about entry of the program. Also, the returned value might not be to the use of JVM, restricting it to void limits extensibility.

So far what I have learnt from this question is : Java specifications have explicitly fixed return type to avoid confusion to migrating programmers (C/CPP) who may expect this value to return to OS, but since JVM is in-between this value will never be returned to OS. For this special purpose (returning value to OS) they have provided System.exit() method.


For all those who are suggesting that return type is part of signature-- Just try to define both of the following methods in a class

    public static void main(String[] a){

    }
    public static String main(String[] a){

    }

You will get a compilation error, because signature of both of these methods is same.

Community
  • 1
  • 1
Mohit Kanwar
  • 2,962
  • 7
  • 39
  • 59
  • 8
    The JVM does this because the specification says so, but I'm assuming you want to know why the specification says so. – user253751 Jun 30 '15 at 05:31
  • yes.. Why is it specified like this? – Mohit Kanwar Jun 30 '15 at 05:31
  • Because you tend to use `System.exit` to define exit levels. The real question is, who wants to know what `main` returns anyway? – MadProgrammer Jun 30 '15 at 05:32
  • Also: see [here](http://csis.pace.edu/~bergin/KarelJava2ed/ch2/javamain.html) for more info on the main class – UnknownOctopus Jun 30 '15 at 05:36
  • 2
    My question is still not answered!! WHY!!! No one is talking about "WHY" is it not allowed. Everyone is marking it as duplicate or answering this is "HOW" it should be. My question is "WHY". Please remove this duplicate mark until you are answering my exact question. – Mohit Kanwar Jun 30 '15 at 05:51
  • @MadProgrammer It is just that It is not in synch with my Java Understanding. e.g. if a method public static void someMethod(){} is modified to public static int someMethod(){ return x} It has no effect on the call someMethod(); It would work perfect, no compilation failure. I understand this as return type is not part of method signature, It should be fine. but as soon as the method in concern is public static void main(String[] args) This breaks my understanding. :( – Mohit Kanwar Jun 30 '15 at 05:59
  • 3
    @CodeFighter The problem you seem to be having, is you can't accept the answer "that's the way it was designed", a decision was made by the creators to make the main entry point `public static void main(String[])`. There could be many reasons for this, you're asking for a time machine and a mind reader to get the answer. – MadProgrammer Jun 30 '15 at 06:06
  • 3
    @CodeFighter There is little point for `main` to have any return value because the JVM may not exit when `main` exists anyway, it's guaranteed to exit when `System.exit` is called or the only running `Thread`s are daemon threads, so, what's the point of having return a value which could either be ignored or changed? – MadProgrammer Jun 30 '15 at 06:06
  • We can call main method from other main methods, or any method for that matter. It might be useful there, when the program is not exiting, just a sub-program is finishing its execution. May be in a scenario, where an application is built up with multiple smaller applications, which can be run independently, and from another application as well. – Mohit Kanwar Jun 30 '15 at 06:12
  • 2
    @CodeFighter This is true, but generally speaking, it's what it was designed for. The JVM places a required on the method signature which forms a contract which we are obligated to follow. It'd be like saying why you can't change the return type of a interface method, the language specifications prohibit it. – MadProgrammer Jun 30 '15 at 06:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81932/discussion-between-code-fighter-and-madprogrammer). – Mohit Kanwar Jun 30 '15 at 06:15
  • @MarkRotteveel. I added the explanation. If not stackoverflow, is there any other site on stackexchange platform where we can get answers to design related questions? – Mohit Kanwar Jul 17 '15 at 06:40
  • If you want to 'reuse' a main with a return code, just use a different method name as the entrypoint for in-process reuse and call that method from your real `main` as well. – Mark Rotteveel Jul 17 '15 at 06:42
  • @MarkRotteveel Other options are available, just wanted to know why is definition of method signature broken for main method. – Mohit Kanwar Jul 17 '15 at 06:45
  • I think you should step away from calling it "broken" it is intentional, not broken. – Mark Rotteveel Jul 17 '15 at 07:05
  • I believe your answer is in this comment. http://stackoverflow.com/a/540419/1119473 The reason is multi-threading. – Gondy Jul 17 '15 at 07:26
  • I think because the JVM does not need the return value, so they decided to fix the signature to make the execution path for the JVM more clear. – Hossein Jul 20 '15 at 07:29
  • @Hossein but the return type is not a part of method signature. – Mohit Kanwar Jul 20 '15 at 08:36

12 Answers12

24

The main is void is specified in JLS 12.1.4 Invoke Test.main:

The method main must be declared public, static, and void.

Sometimes the answer to a why? is because the specification says so (aka Quod Ego Dixit, or Because I Say So (Terry Pratchett)). Sometimes the decisions of a language designer are not available and the only thing we can do is guess. This is also the reason the obvious duplicate (Why is main() in java void?) is closed as primarily opinion-based.

Now as the - to me - obvious reason: JLS 12.8 Program Exit says:

A program terminates all its activity and exits when one of two things happens:

  • All the threads that are not daemon threads terminate.
  • Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.

This means that the end of the main method does not necessarily mean the end of the program. A return code from a main method has a well-known meaning in languages like C: it is the process exit code. This meaning doesn't apply when the main method may exit long before the process itself ends.

Most non-trivial Java applications have - usually- a short-lived main method that kicks off one or more long-living non-daemon threads. Allowing a return code from a Java main method could imply a meaning that is not actually there: that the return value is the process exit code. So explicitly specifying that main must have a void return type is good thing: it reduces confusion or assigning meaning that isn't there.

Community
  • 1
  • 1
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
20

The main method may not be an exit point after all. Due to multi-threading it may happen that when the main returns there's still another thread on the pitch keeping the program alive. An exit code makes no sense in this case.

dly
  • 1,080
  • 1
  • 17
  • 23
12

Why not void?

If you wish to return some status to OS you can use any of exiting methods.Most common one being System.exit(int status) .

If your main finishes before the other threads, a return value won't matter. This is in contrast with c/c++ which do not supported multi-threading that time.

Like a swing application may still work on EDT after finishing main.

And if you are still considering the "entry" point: but the return type always talks about the exit.

So it's simply void as we have status signallers to return a value or no return in other case. Still, there is no other point because it was designed in this way.Another developer with different thoughts might throw another idea to solve same situation.Depends.

joey rohan
  • 3,505
  • 5
  • 33
  • 70
8

As stated in http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.8

12.8. Program Exit

A program terminates all its activity and exits when one of two things happens:

All the threads that are not daemon threads terminate.

Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.

the program exits, if all running threads are deamon. So if you have a non deamon thread, the main method might return before the program ends.

The lifetime of your program can extend the lifetime of the main method and the return number might be decided later in the program.

I think this is why they use System.exit() as return point.

red13
  • 427
  • 4
  • 12
5

You can't look at below from Java Docs, for your main method to serve as exit point you need to have the method void. or you have an option to call system.exit() explicitly at the end of you main.

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

kuhajeyan
  • 10,727
  • 10
  • 46
  • 71
  • 1
    My question is "Why" does it not serves as exit point when the method is returning something. The only effect would be the returned value is not being used anywhere. – Mohit Kanwar Jun 30 '15 at 05:42
5

As per my knowledge,

The reason for the main method having void as return type is that, once the main method finishes its execution, it doesn't mean that the entire program finished. It may have some threads initiated and running behind the scene. Even if the main thread is dead, still there is a chance of child threads to be running. In this case the return type of main doesn't make much sense.

And JVM will monitor the program completion status to deallocate the memory, Its not necessary to return something to JVM that states the program is finished. In C-language we are directly communicating with O.S. so, there is an option to return int value to O.S. that states the execution is done and start deallocating the memory. But here in java, JVM will communicate with O.S. but not the program, So we no need to return anything from main.

Hope this clears your doubt.

Community
  • 1
  • 1
Manindar
  • 999
  • 2
  • 14
  • 30
4

If you ask JVM to run a class, java runtime will look for exactly that signature in your class public static void main(String[] args) That is your contract with the JVM, if not, it will not execute. If you want an int code back, use System.exit

Jukey
  • 41
  • 2
4

A console program returns an int return code, and thus in a traditional C program an int main(int argc, char** argv) seems logical.

In Java the exception was introduced as a new control flow mechanism, and also multi-threading was simulated or now implemented. Exit could be done everywhere with System.exit(int returnCode).

This means that the call to main is embedded in a piece of code, and cleanest (minimalistic, less cases, no magic of return 0) is to a default of returning 0, except by System.exit.

Mind, java was intended to strongly "improve" upon C and especially C++. Like having Strings and char that use full Unicode as opposed to byte.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
2

Java has been designed as a Platform independent language. So if it's main() method returns a value (like 0 or 1 or anything), it can be interpreted or understood differently by different platform. So, unlike C and Cpp it's main() method can't return a value.

Manindar
  • 999
  • 2
  • 14
  • 30
  • But, Java doesn't returns to OS directly, I suppose JVM is there in between. hence the returned value won't go to OS, until exit() is used. – Mohit Kanwar Jul 22 '15 at 05:16
2

The main reason is that in common use cases particularly in multi-threading and GUI apps you don't prefer to have a return value in main. But if really you have such a use case, you can use exit method. This is the reason that you are looking for.

Mohit Kanwar
  • 2,962
  • 7
  • 39
  • 59
user3359139
  • 430
  • 4
  • 17
1

What is main method in Java?

Main method in Java is entry point for any core Java program. Remember we are not talking about Servlet, MIDlet or any other container managed Java program where life cycle methods are provided to control the execution. In core Java program, execution starts from main method when you type java main-class-name, JVM search for public static void main(String args[]) method in that class and if it doesn't find that method it throws error NoSuchMethodError:main and terminates.

Signature of main method in Java

Main method has to strictly follow its syntax; other wise JVM will not be able to locate it and your program will not run. Here is the exact signature of main method:

public static void main(String args[])

This signature is classic signature and there from start of Java but with introduction of variable argument or varargs in Java5 you can also declare main method in Java using varargs syntax as shown in below example:

public static void main(String... args)

Remember varargs version of java main method will only work in Java 1.5 or later version. Apart from public, static and void there are certain keywords like final, synchronized and strictfp which are permitted in signature of java main method.

Why main method is static in Java

why main method is public static void in JavaNow come to the main point "Why main method is static in Java", there are quite a few reasons around but here are few reasons which make sense to me:

  1. Since main method is static Java virtual Machine can call it without creating any instance of class which contains main method.

  2. Since C and C++ also has similar main method which serves as entry point for program execution, following that convention will only help Java.

  3. If main method were not declared static than JVM has to create instance of main Class and since constructor can be overloaded and can have arguments there would not be any certain and consistent way for JVM to find main method in Java.

  4. Anything which is declared in class in Java comes under reference type and requires object to be created before using them but static method and static data are loaded into separate memory inside JVM called context which is created when a class is loaded. If main method is static than it will be loaded in JVM context and are available to execution.

Why main mehtod is public in Java

Java specifies several access modifiers e.g. private, protected and public. Any method or variable which is declared public in Java can be accessible from outside of that class. Since main method is public in Java, JVM can easily access and execute it.

Why main method is void in Java

Since main method in Java is not supposed to return any value, its made void which simply means main is not returning anything.

Summary:

  1. Main method must be declared public, static and void in Java otherwise JVM will not able to run Java program.

  2. JVM throws NoSuchMethodException:main if it doesn't find main method of predefined signature in class which is provided to Java command. E.g. if you run java Helloworld than JVM will search for public static void main String args[]) method in HelloWorld.class file.

  3. Main method is entry point for any Core Java program. Execution starts from main method.

4. Main method is run by a special thread called "main" thread in Java. Your Java program will be running until your main thread is running or any non-daemon thread spawned from main method is running.

  1. When you see "Exception in Thread main” e.g. Exception in Thread main: Java.lang.NullPointerException it means Exception is thrown inside main thread.

  2. You can declare main method using varargs syntax from Java 1.5 onwards e.g. public static void main(String... args)

  3. Apart from static, void and public you can use final, synchronized and strictfp modifier in signature of main method in Java.

  1. Main method in Java can be overloaded like any other method in Java but JVM will only call main method with specified signature specified above.
  1. You can use throws clause in signature of main method and can throw any checked or unchecked Exception.

  2. Static initializer block is executed even before JVM calls main method. They are executed when a Class is loaded into Memory by JVM.

I hope this has answered your question about the main method :)

Update in response to:

One small problem with your answer: Return type is not a part of method signature.. hence, JVM must not throw the exception "NoSuchMethodException:main" if the return type is different.

it doesn't return "NoSuchMethodException:main" if the return type is different and the return type is a part of the method signature. Take a look at this screenshot:

enter image description here

triForce420
  • 719
  • 12
  • 31
-1

We can say, main method as class initilization method, since it satisfies one of the class initilization criterion; Please refer http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4, 12.4.1 section--

T is a class and a static method declared by T is invoked.

Now, as per JVM specification, return instruction is used to return from methods declared to be void, instance initialization methods, and class or interface initialization methods. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.11.8

Please see details about return instruction here: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.1.9.return

Ashish Patil
  • 4,428
  • 1
  • 15
  • 36