In Java, which declaration of the main()
method is valid?
We commonly use public static void main(String[] arr){}
, but what I want to know is: can the main()
method be declared final?
final public static void main(String[] arr) {
//...
}
In Java, which declaration of the main()
method is valid?
We commonly use public static void main(String[] arr){}
, but what I want to know is: can the main()
method be declared final?
final public static void main(String[] arr) {
//...
}
Yes, you can mark main
final
.
While it is possible, it is not really meaningful. final
methods can not be overriden. But static methods cant anyways, since they are not inherited when extending.
However, it has an effect when actually hiding by introducing a method with the same name in an extending class. See Behaviour of final static method.
A contrived example to this:
public class A {
public static void main(String[] args) {
System.out.println("Hello from A");
}
}
public class B extends A {
public static void main(String[] args) {
System.out.println("Hello from B");
}
}
Suppose you are calling those methods manually:
A.main(null); // "Hello from A"
B.main(null); // "Hello from B"
Note that Java also allows to call static
methods from instances:
A a = new A();
a.main(null); // "Hello from A"
B b = new B();
b.main(null); // "Hello from B"
But what if you reduce the view of a B
object to an A
object:
A bAsA = new B();
bAsA.main(null); // "Hello from A"
And this might be surprising. Since, usually, it will take the method from the actual instance, which would be B
. But that only applies when you are actually overriding methods, which is never the case with static
methods.
Marking main
as final
will result in no subclass being able to hide your method anymore. That is, B
will not be able to declare a method main
anymore (with the same signature). The above code will then not compile.
The short answer is Yes.
You can declare main method as final. without any compile error.
public class Car {
public final static void main(String[] args) throws Exception {
System.out.println("yes it works!");
}
}
Output
yes it works!
But when we use inheritance concept. we cannot declare the main method as final
. if it is parent class.
public class Parent {
public final static void main(String[] args) throws Exception {
System.out.println("Parent");
}
}
class Child extends Parent {
public static void main(String[] args) throws Exception {
System.out.println("Child");
}
}
Output: Cannot override the final method from Parent .
But you can declare the final method in child class main method.
public class Parent {
public static void main(String[] args) throws Exception {
System.out.println("Parent");
}
}
class Child extends Parent {
public final static void main(String[] args) throws Exception {
System.out.println("Child");
}
}
Output:
Parent
Child
There is no such restriction in the JLS although I expected it to be sincr such combination of modifiers is meaningless (in almost all cases as @Zabuza noted). In fact, there are only 3 restrictions on applying modifiers
I
It is a compile-time error if the same keyword appears more than once as a modifier for a method declaration, or if a method declaration has more than one of the access modifiers
public
,protected
, andprivate
II
It is a compile-time error if a method declaration that contains the keyword
abstract
also contains any one of the keywordsprivate
,static
,final
,native
,strictfp
, orsynchronized
.
III
It is a compile-time error if a method declaration that contains the keyword
native
also containsstrictfp
.