The below picture shows that "Checked" and "Unchecked" Exceptions are subclasses of Exception. I find it confusing that you need to catch an Exception but you don't need to catch a RuntimeException, which directly inherits from Exception. Is there a reason that the devs didn't let us throw Exceptions without needing to catch them?
More specifically: Why can you ignore only RuntimeExceptions and it's children? Why wasn't there a Class introduced called CheckedException extends Exception and you only need to catch it and it's children?
The confusing part is, that you can throw everything below RuntimeException without issue, but when you move up to Exception in the hierarchy, you need to catch it at some point. This is confusing because "abstraction" normally works otherwise. The more you move up, the simpler and more meta everything gets. This is not the case here. The more you move up, the more you have to do (like, putting try/catch after reaching Exception).
If Exception was unchecked then you could implicitly cast checked exceptions to unchecked ones, which would mean that you could throw checked exceptions without catching them like:
public void f() {
Exception e = new IOException();
throw e;
}
and also with overriding methods, if you throw a more specific exception, you can add the requirement to catch the exception that wasn't in the superclass:
public void f() throws Exception {
}
...
#Override
public void f() throws IOException {
}
Suppose they designed it the other way. We have a CheckedException class, and subclasses of that need to be handled, but not other subclasses of Exception.
Now we call a method that might throw an arbitrary Exception:
public static void example() {
functionThatThrowsException();
}
Do we need to handle it? Yes, because that Exception might be a CheckedException. If we didn't need to handle it, we'd be bypassing the checked nature of checked exceptions.
A throwable type with checked descendants must be treated as checked, so checkedness naturally propagates up the inheritance hierarchy. Contrapositively, an unchecked throwable type cannot have checked descendants, so uncheckedness naturally propagates down. This makes it natural to make checkedness the default, and single out specific classes and their descendants as unchecked.
CheckedException (Which does exist) and RuntimeException both extend Exception. Because of this, if something throws a generic Exception (which is always a bad idea), there is no way to tell if the exception could be one or the other, so you have to catch it in case it's a checked one. If you think of the hierarchy in this way, it actually does get simpler the farther up you go.
You seem to have the idea that checked exceptions are more "complex" because you have to do more to work around them. This isn't too healthy a way of thinking about it. Instead, consider this: Exceptions are problems with the program itself - the code. We need to find these exceptions and handle them properly. After already having this concept of exception handling, we discover that there are some problems that we simply can't predict.
"How was I supposed to know the user would enter 'meow' when asked for an integer! I shouldn't have to code around that!" And so, NumberFormatException was born, and you don't have to catch it because it's a "logical error", not an issue caused by bad code (Although, arguably, it might be considered bad code if you don't handle this situation in some way).
In short, reverse your thinking. Exceptions are problems with the program that can be handled. There are some exceptions, however, that are unexpected and are a result of bad design more than incorrect code. Thus there is the addition of RuntimeExceptions which cannot possibly be expected to occur, but certainly can occur.
Perhaps it would help to not think of exception classes in terms of inheritance but simply disjoint sets of classes, one set is checked and other is not. You're right that there could be a CheckedException class allowing us to check only when explicitly intended.
However having the broader/generalized range checked helps in enforcing the catch or specify pattern. Having checked exception allows a reader of the code to figure out quickly that this piece of code needs special attention and enforcing their handling at compile time reducing the runtime bugs.
We can throw any kind of exception, checked or unchecked. If Exception or any super class of RuntimeException were to be set as checked exception then all the sub classes would become checked exceptions. As compiler is most likely checking if an instance of exception or a class in the throws clause derives from a class. It could easily have done that by checking for a specific package which probably would have been more appropriate as being checked or unchecked has simply nothing to do with the inheritance.
Related
Java Runtime Exception is used to check un-checked exception. It is accepted standard that to sub class JavaRunTimeException. Can you please explain me the reason behind sub classing without directly using it as below.
try {
int x = Integer.parseInt(args[0])/Integer.parseInt(args[0]);
} catch (RuntimeException e) {
}
Recommended approach
public class ServiceFaultException extends RuntimeException {}
try {
int x = Integer.parseInt(args[0])/Integer.parseInt(args[0]);
} catch (ServiceFaultException e) {
}
I would like to know reasons for this recommendation. ?
Exceptions are used to give some meaning to an error that is not handled right away where it occurs.
Subclassing RuntimeException allows you to give more meaning and differentiate between several RuntimeExceptions.
For instance, it is useful to be able to tell the difference between IllegalArgumentException and NumberFormatException, which are both RuntimeExceptions.
EDIT: As #Dyrborg said, catching RuntimeException can also be dangerous because anything could throw it without your knowledge. Better handle only what you control.
ASIDE:
You could tell me "why not a checked Exception then ?".
I usually use RuntimeExceptions when it corresponds to an incorrect use of a method (illegal argument for instance). It means something the programmer can ensure to avoid. When it comes to user input, or internet connection, which is not reliable, then Exceptions are more appropriate, because the programmer must handle these error cases.
Can you please explain me the reason behind sub classing without directly using it as below.
The same reason as applies to subclassing any other exception. The language provides the facility to catch specific subclasses, so why wouldn't you use it?
This is my code:
public static void main(String[] args) throws Exception {
Scanner s = new Scanner(new File("story.txt"));
someFunction(s);
}
The story.txt is in the the project root, but without the throws Exception the code doesn't run.
Why?
You don't need throws Exception, but it won't hurt any if you leave it like that.
What you do need is a throws FileNotFoundException because the Scanner constructor you are using is declared to throw that exception, and you don't catch any exceptions.
You should throw a FileNotFoundException, because the Scanner constructor can throw one. Since it is a checked exception, you must either pass it further up the stack or handle it somehow.
I asked my professor, and he explained that Java makes you handle exceptions.
You must be ready for them if a function might throw them.
You can either use:
try {...
} catch { ...
}
to handle exceptions yourself, or you can use:
throws Exceptions
to "pass them to the next level" (handle them later).
Thanks for the help!
If a method or constructor either throws an exception which isn't derived from RuntimeException, or calls any method whose declaration indicates it must do so, then it must either catch that exception or declare that the exception may be thrown from it. This language feature is almost a good thing, but in its present form has been widely acknowledged as a mistake. Nonetheless, it is sufficiently firmly established as part of the Java language that it's not going anywhere.
Conceptually, it's good to make a distinction between exceptions which are likely to have special meaning to a method's immediate caller and those which would not. Unfortunately, the fact that an exception would have a special meaning to its immediate caller doesn't mean the immediate caller is going to be interested in it. The way Java implements checked exceptions, if Foo is declared as throwing a checked exception and Bar calls Foo but isn't prepared to handle that exception, it must either declare itself as throwing that exception (even though it's unlikely to have any special meaning to its caller), or else catch the exception it has no hope of handling (perhaps rethrowing as a type derived from RuntimeException). Catching and rethrowing as a type derived from RuntimeException is semantically the best approach, but ends up being the most verbose, especially if one wants to avoid making RuntimeException objects.
Note also that because there's no way a chained constructor call can be wrapped in a try block, any constructor which is chained through a constructor that is declared as throwing any exceptions is required to declare itself as throwing those same exceptions. Things are implemented that way for a reason, but it unfortunately makes it difficult for a class constructor to distinguish exceptions which got thrown as part of the base-class construction process and those which got thrown in the construction of the derived class.
Because, Scanner s = new Scanner(new File("story.txt")); throws checked FileNotFoundException. You should throws or catch checked exception for compilation.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
The Java specification requires that if an exception is thrown, it is either handled by a try/catch statement, or that the function is declared with "throws XYZException". This has the exception of RuntimeException, where it is OK if this is thrown without being caught.
This might sound like a matter of opinion, but the more I think about it, the more it seems really counter-intuitive:
Why is it that we have a RuntimeException extending Exception?
When I first started doing Java, I thought ALL exceptions had to be caught in that way, and it made sense because all exceptions extend Exception. It seems like a violation of OOP to have a RuntimeException exception exception :P. Since RuntimeException makes throws kinda redundant, why didn't Java allow all exceptions at runtime in the first place, adding a throws only when you want to force the caller to handle that type of exception?
Examples:
void noThrows() {
throw new Exception();
}
... no errors.
void hasThrows() throws AnyBaseOfXYZException {
throw new XYZException();
}
... no errors.
void testFunction() {
hasThrows();
}
... fails since "hasThrows" throws AnyBaseOfXYZException, and this is not handled
void testFunction() {
try {
hasThrows();
} catch (AnyBaseOfXYZException e) {
...
}
}
... no errors.
I'd thought about maybe some kind of "CompileTimeException" that extends Exception, but when you give it enough thought, it just can't work without being as ugly as RuntimeException.
Basically, why did Java decide to force all exceptions to require throws except for RuntimeExceptions, when all exceptions could be runtime exceptions except when otherwise stated with throws?
Firstly, the base class of all things that can be thrown is Throwable (not Exception).
Under Throwable are two subclasses: Exception and Error.
Under Exception is RuntimeException.
Of these 4 main classes, RuntimeException and Error are unchecked (may be thrown without having to be declared as being thrown).
The idea behind RuntimeException being unchecked is that it's typically a programming error and that normal good practice should avoid them (eg ArrayIndexOutOfBoundsException or NullPointerException) and to require them to be caught would clutter up the code massively.
The reason Errors are unchecked is that basically, there's nothing you can to about it if one happens, eg OutOfMemoryError etc.
That leaves all other Throwables, ie subclasses of Exception, must be declared as thrown or caught. The idea behind this is that checked exceptions can be "handled by the caller". eg FileNotFoundException (we know what this means and should know what to do if we get one).
The Java designers didn't always get this right. SQLException is checked, but there's no realistic way to recover - do I have a syntax error in my query? is the database refusing conections? who knows, but I do know I can't "handle" it.
In some cases you want to have a catch that catches all exceptions: checked and unchecked.
Java's design decision allows you to achieve that with catch (Exception e) { ... }
If unchecked exceptions (exceptions that extends RuntimeException) were not extending Exception then you had to use two catch clauses.
This might be related to topic of check and uncheck exception. From RuntimeException
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions
do not need to be declared in a method or constructor's throws clause if they can
be thrown by the execution of the method or constructor and propagate outside the
method or constructor boundary.
Check exception is to be use for case that recoverable when the program is executed. So it makes perfect sense to force programmer writing the class to declare it in a method definition. By doing so the caller will be force to catch it or re throw it.
However uncheck exception is for a case that is unrecoverable and thus it is better to terminate. This case is rarely happen (usually happen when the code is still being developed) and thus this usually indicate a programmer error or a very fatal bug that usually need to fix by the class writer and is not recoverable by the client of the class.
I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Wouldn't it make more sense if Throwable were divided into Exception (checked) and RuntimeException (unchecked), and Error would inherit from RuntimeExeption?
I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
A Throwable is anything that can be used to unwind the call stack. This should include some VM level fault (flagged by an Error) and something application specific (flagged by an Exception)
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Simply because Errors are not Exceptions. There wouldn't be any point in actually "catching" an Error. For eg. What would you do after catching an OutOfMemoryError. Errors are meant to flag something seriously happened at the VM level which is not necessarily handle-able by the programmer
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Not really. What the implementors were trying to say was that Exceptions MUST always be checked. Your code will be cleaner if all your methods declare what sort of application/library Exceptions they throw. RuntimeExceptions should only be thrown in case of more general / dynamic situations such as a NullPointerException where the developer might not have coded for the case but is a serious bug which is not exactly something mentioned in the application spec.
The design of exception handling in the two most popular object-oriented frameworks (Java and .NET) is predicated upon the notion that the question of whether to handle a particular exception should depend primarily upon its type, and that the types of exceptions one will want to catch are going to have a hierarchical class relationship. I think Java and .NET do things that way because C++ did it that way, and C++ did it that way because of a desire to avoid hard-wiring any non-primitive types hard-coded into the language. In the absence of a hard-coded type to which all exceptions may be cast, it's impossible for a catch statement to know anything about any exception type for which it is not explicitly prepared. If it will only make sense to catch exceptions one can decode, a catch statement will be able to sensibly act upon those types, and only those types, which derive from the one in the statement.
In retrospect, it probably would have been better to have the decisions of what exceptions should be acted upon and/or resolved by particular catch statements be determined by some means other than the class hierarchy. Among other things, a single attempt to invoke a method may fail because of multiple problems; if that happens, every catch which is associated with any of those problems should trigger, but only when all of the problems have been resolved should normal execution resume. Unfortunately, neither Java nor .NET has any mechanism to achieve such behavior.
With regard to the top-level layout of the hierarchy, I think there was an assumption that every kind of exception that might be thrown by a method would either always be expected by the immediate calling code or never expected by any calling code. Exceptions of the latter type were classified under Error or RuntimeException, while those of the former type were placed elsewhere. In practice, the question of whether an exception is expected by a method's caller should be independent of its place in the hierarchy or even the exception type. The fact that a method is declared as throws FooException does not mean that calling code is always going to expect that the exception could occur. It's very common for code to call a method which is declared as throwing an exception but believe that the circumstances surrounding the call are such that in practice that the particular call won't ever throw.. If the exception does occur, it should behave like an unexpected exception, even if an outer execution context is expecting to catch an exception of that type. Unfortunately, the exception handling mechanisms are what they are, and I don't expect any major overhaul.
I think that even better hierarchy is
Throwable
Exception
CheckedException
RuntimeException
Error
This hierarchy separates Exceptions and Errors (as #Paarth said) and makes it possible to catch all checked exceptions only (without runtime exceptions). But it seems that James Gosling thought different...
Error is not a subclass of Exception because it is not meant to catch (Once an error is occurred usually the program is no longer expected to function). So error should have more higher place in hierarchy as I believe.
It should not violate Liskov substitution because RuntimeException can be catched if you want, but only it's not enforced.
While reading about exception, I will always come across checked exceptions and unchecked exceptions, So wanted to know how to distinguish that which is what?
Edit: I want to know if i create any exception class then how can i create as a checked or as an unchecked?
and what is the significance of each?
All Throwables except subclasses of java.lang.RuntimeException or java.lang.Error are checked. Properly, in Java, "exceptions" are subclasses of java.lang.Exception, "errors" are subclasses of java.lang.Error and java.lang.Throwable is not usually subclassed directly.
Programs are not supposed to create their own Error subclasses (though the documentation is rather ambiguous on that) so generally you always create Exceptions, using a RuntimeException if you don't want it to be checked.
To know at run-time if you have a checked exception you could use:
if(throwable instanceof Exception && !(throwable instanceof RuntimeException)) {
// this is a checked Exception
}
A checked exception is one which must be either handled in a catch clause, or declared as being thrown in the method signature; the compiler enforces this. Generally, one uses checked exceptions for exceptions which should be handled by the calling code, while unchecked exceptions are for conditions which are the result of a programming error and should be fixed by correcting the code.
That said there is much debate in the Java community about the efficacy of using checked exceptions vs. unchecked exceptions everywhere - a subject way to deep to discuss in this answer.
EDIT 2012-10-23: In response to comments (which are quite valid), to clarify, the following would be what is required to determine if a captured Throwable is a checked Throwable as opposed to a checked Exception:
if(obj instanceof Throwable && !(obj instanceof RuntimeException) && !(obj instanceof Error)) {
// this is a checked Throwable - i.e. Throwable, but not RuntimeException or Error
}
If the object in question is known to be an instance of Throwable (e.g. it was caught), only the second part of the above 'if' is needed (e.g. testing for Throwable is redundant).
See the Java Language Spec, chapter 11:
The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. The Java API defines a number of exception classes, both checked and unchecked. Additional exception classes, both checked and unchecked, may be declared by programmers.
You could check this via instanceof at runtime, though I don't really see where this would be useful.
As to the second part of your question:
checked exception represent expected error conditions, which can occur during normal program execution and therefore always have to be handled programatically (which the compiler enforces)
unchecked exception represent unexpected error conditions and signify an abnormal state of your program, due to invalid input, bugs or runtime restrictions (eg memory); the compiler won't force the programmer to handle these, ie you only have to care for them if you know of their occurrence
Java checked vs unchecked exception
Error is internal VM error and usually you can not manage it.
Exception - you are able to catch and handle it
Checked vs Unchecked
checked exception is checked by the compiler and as a programmer you have to handle it using try-catch-finally, throws
unchecked exception is not checked by the compiler but you optionally can manage it explicitly
IntelliJ IDEA's Type Hierarchy tool is useful when you want to find more
If the exception class is a subclass of RuntimeException, it's not checked and does not have to be declared for functions or caught, etc. Error exceptions also do not have to be declared/caught. Is that what you're asking?
Quite sure this will have been asked and answered before, but for the sake of it, it is covered quite nicely here: http://www.javapractices.com/topic/TopicAction.do?Id=129.
Strictly speaking, unchecked exceptions will always extend RuntimeException whereas checked exceptions do not. The mentioned link explains when to use either.
As their name indicates, callers are obliged to deal with checked exceptions, typically handling them (try/catch) or passing them further up the stack. Unchecked exceptions are usually deemed to be caused by elements outside of the caller's control.
package practice;
import java.io.IOException;
class Practice
{
public static void main(String args[])
{
Exception n=new NullPointerException();
if(n instanceof RuntimeException)
{
System.out.println("this is a runtime(unchecked) exception");
}
else
{
System.out.println("this is not a compiletime(checked) exception");
}
}
}