@Suresh let me correct your concept of overriding method in case of throw clause: An overriding method can throw All, None, Subset or subclass exceptions of the exceptions declared in throws class of overridden method in case of checked exceptions. Compiler validates this rule in case of checked exception only not in case of unchecked exceptions defined in throws clause.
Now consider your code you have defined unchecked exception in your overriding method's throws clause. so compiler will not gives any error in this case.
Note: java.lang.RuntimeException , java.lang.Error and their subclass comes under checked exceptions.
Hope it clears your doubt.
Do let me know if anything remains unclear.
That was helpful. Actually I too had same doubt as Suresh with the following code snippet:
Since the thread is about 1½ years old, there is a possibility that you won't get a response from the original poster.
I have added code tags, which you should always use, to your post. Doesn't it look better!
Don't use com.test as a package name since that domain is already in use. Look here for package names. In fact on the beginning forum you might do well to omit the package names since some people wouldn't know how to compile the code in packages.
Please tell us where the quote at the beginning of your post comes from.
The idea of inheritance is that a subclass IS‑A superclass and a subclass object IS‑A superclass object. And the Liskov Substitution Principle (=LSP) says that every subclass method must be called as one would call a superclass method without any surprising behaviour. So, if you have a method which does not throw an Exception then you will be very displeased to use its overridden version in a subclass and suffer an Exception. Example:- In Object#equals it says
Now, you know a method without void return type must return something and the only way it can get out of returning something is to throw an Exception. If it always returns something, that does not allow for Exceptions. That means that equals() methods are not permitted to throw Exceptions. Now what about this sort of implementation of equals:-That is an incorrect implementation because it will throw a null pointer exception if you pass a null reference. There is no problem about getClass() because I marked the class final.
The API's 4th & 5th bullet points wrote:for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false.
What you are saying with throws CloneNotSupportedException is that your method might throw it. The compiler notices because it is a checked Exception. Even though the method does not actually throw it, an overriding might. So it passes. When you get to the subclass methods, they have incorrect declarations because they are not subtypes nor a subset of the superclass' declarations. Throwing those Exceptions might breach the LSP, but the compiler ignores them because they are unchecked type.
Unchecked Exceptions are unchecked because you usually have to correct the code to prevent the Exception, and Errors are unchecked because they are usually not possible to recover from. AssertionError should be a runtime exception, but when assert was added in J2SE1.4 they thought it should be an Error so as not to be caught by catch (Exception ex) statements. As well as that, it is often difficult to predict when an unchecked Exception occurs (look at null pointer exceptions), so they thought it best not to check for them.
You can get away with unchecked Exceptions in overridings not because they are permissible but because the compiler ignores them. There is a lot about Exceptions in the Java Tutorials.
And you can find even stranger design in this class.
A few minutes ago, I wrote: . . . they thought it should be an Error . . .
@Campbell: Thank you for that wonderful response.
A few days ago, one of my colleagues asked a question which read something like:
Suppose a superclass method declared as "int returnNum() throws CloneNotSupportedException" is overriden in subclasses.
Which of the following overriding declarations in subclasses are improper?
int returnNum() throws RuntimeException int returnNum() throws AssertionError int returnNum() int returnNum() throws Exception
All that I knew then about method overriding was:
"All are incorrect, except the third option.", was my immediate reply to her.
But, when compiled and ran the code snippet from my previous post, the first three options comiled fine except for the last option!
RuntimeException(unchecked) is a subclass of Exception and a sibling to CloneNotSupportedException(checked).
AssertionError(unchecked) is a subclass of Error(unchecked).
I was confused because these exceptions and errors were not in superclass-subclass relationship. Also, unchecked and checked exceptions were mixed in options.
Here, in superclass method, the exception being thrown is CloneNotSupportedException(checked). So, Shaddy Khan's earlier post cleared the mist.
Shaddy Khan wrote:An overriding method can throw all, none, subset or subclass exceptions of the exceptions declared in throws class of overridden method, in case of checked exceptions. Compiler validates this rule in case of "checked exception only" and not in case of unchecked exceptions defined in throws clause.
So, my questions are: