Recently I was playing around with some simple Java code using main methods to quickly test the code I wrote. I ended up in a situation where I had two classes
The point is that we are talking about static methods, which indeed are not supposed to be impacted by polymorphism. However, it seems to me that static methods belong to a Class object, which just like any other object should obey to polymorphism, right ?
For what it's worth, here is the relevant portion of the JLS that enforces this rule.
First, §8.4.8.2. Hiding (by Class Methods) gives a definition for method hiding that applies here:
If a class C declares or inherits a
staticmethodm, thenmis said to hide any methodm', where the signature ofmis a subsignature (§8.4.2) of the signature ofm', in the superclasses and superinterfaces of C that would otherwise be accessible to code in C.
Then, §8.4.8.3. Requirements in Overriding and Hiding states that:
A method that overrides or hides another method, including methods that implement
abstractmethods defined in interfaces, may not be declared to throw more checked exceptions than the overridden or hidden method.More precisely, suppose that B is a class or interface, and A is a superclass or superinterface of B, and a method declaration
m2in B overrides or hides a method declarationm1in A. Then:
If
m2has athrowsclause that mentions any checked exception types, thenm1must have athrowsclause, or a compile-time error occurs.For every checked exception type listed in the
throwsclause ofm2, that same exception class or one of its supertypes must occur in the erasure (§4.6) of thethrowsclause ofm1; otherwise, a compile-time error occurs.
In other words, the error message is not some oversight in the compiler, or a misinterpretation of the spec; the JLS makes the specific effort to mention that throws clause conflicts are an error with method hiding (i.e., with static methods). There is equivalent language to this in every version of the JLS back to 1.0.
However, I can't definitively answer your question of why the constraint is present in this case. I can't conceive of any situation in which the constraint is necessary, since the issue of which static method implementation is invoked is always completely resolved at compile-time, unlike for instance methods.
I'd bet a small amount of money that whoever first put that constraint in the langspec was simply being over-cautious, figuring it was safer to prevent something than to allow it and then later discover it causes problems. The Java language design is/was not without its fair share of flawed features (checked exceptions being one of them), and this could credibly be another, but this is just a guess.
I've never have realised about this fact, but after analyzing it accurately, I see no reason why the compiler should enforce such a constraint. Altough it didn't, there would be no possible incoherence when matching the main method, for the linking of a static method is also static. No overriding is allowed in this case.
The 'extends' keyword means that you are inheriting the methods from Class A when you declare Class B. Since you Class A is the parent class of Class B, the main method's declaration still lies in Class A despite the fact that you are redefining it in Class B.
When you are dealing with static methods, the parent class method is not overwritten by the subclass, it is simply hidden.
http://docs.oracle.com/javase/tutorial/java/IandI/override.html
Can provide more detail but here is an excerpt:
The distinction between hiding a static method and overriding an instance method has important implications:
The version of the overridden instance method that gets invoked is the one in the subclass. The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
original answer
This constraint is forced by the compiler to help simplify inheritance in more complicated hierarchies.
Take the toString() method for example. It is inherited by every object in Java, imagine if you were able to override the declaring of this method to allow subclasses to throw different exceptions. That is a recipe for disaster in terms of handling all of those potentially new exceptions.
TLDR- The compiler forces you to obey the parent class function definition so other programmers can sleep at night.