3

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) {
    //...
}
Talendar
  • 1,841
  • 14
  • 23

3 Answers3

13

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.


Hiding

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.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
4

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

Poorna Senani Gamage
  • 1,246
  • 2
  • 19
  • 30
0

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, and private

II

It is a compile-time error if a method declaration that contains the keyword abstract also contains any one of the keywords private, static, final, native, strictfp, or synchronized.

III

It is a compile-time error if a method declaration that contains the keyword native also contains strictfp.

Some Name
  • 8,555
  • 5
  • 27
  • 77
  • 2
    It is not completely meaningless though, it has indeed an effect. A subclass can not declare such a method anymore (not speaking of overriding). So you can kind of *lock* a method signature. I admit that this is an extremely rarely useful tool though. – Zabuzard Feb 10 '19 at 21:33
  • 1
    @Zabuza did not think about such usage, indeed. – Some Name Feb 10 '19 at 21:46