757

Joshua Bloch in "Effective Java" said that

Use checked exceptions for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition)

Let's see if I understand this correctly.

Here is my understanding of a checked exception:

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}

1. Is the above considered a checked exception?

2. Is RuntimeException an unchecked exception?

Here is my understanding of an unchecked exception:

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}

4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I? (Note: my 3rd question is inside the catch above)

try{
    String filePath = //read in from user input file path
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){
    //Kindly prompt the user an error message
    //Somehow ask the user to re-enter the file path.
}

5. Why do people do this?

public void someMethod throws Exception{

}

Why do they let the exception bubble up? Isn't handling the error sooner better? Why bubble up?

6. Should I bubble up the exact exception or mask it using Exception?

Below are my readings

In Java, when should I create a checked exception, and when should it be a runtime exception?

When to choose checked and unchecked exceptions

Yogesh Umesh Vaity
  • 41,009
  • 21
  • 145
  • 105
Thang Pham
  • 38,125
  • 75
  • 201
  • 285
  • 8
    I have a great example of an unchecked exception. I have a `DataSeries` class that holds data which always must remain in time-based order. There is a method to add a new `DataPoint` to the end of a `DataSeries`. If all of my code is working correctly throughout the project, a `DataPoint` should never be added to the end which has a prior date to the one already on the end. Every module in the whole project is built with this truism. However, I check this condition and throw an unchecked exception if it happens. Why? If it happens, I want to know who is doing this and fix it. – Erick Robertson May 24 '11 at 19:53
  • 3
    To add even more confusion. Many people were advocating checked exceptions ~10 years ago, but the view nowdays is more and more moving towards "checked exceptions are bad". (I do however not agree on that) – Kaj May 24 '11 at 19:57
  • related: http://techblog.bozho.net/?p=316 – Bozho May 24 '11 at 20:02
  • 12
    Its is only useful to handle an Exception when you have something useful to do with it, otherwise you should let the caller handle it. Logging it and pretending it didn't happen is usually not useful. Just re-throwing it is pointless. Wrapping in a RuntimeException is not as useful as some think, it just makes the compiler stop helping you. (IMHO) – Peter Lawrey May 24 '11 at 20:18
  • 52
    We should stop using the comprehensively misleading terms of *checked/unchecked* exceptions. They should be called *check-mandated* vs *check-not-mandated* exceptions. – Blessed Geek Jan 24 '14 at 13:22
  • 3
    I have also thought abt ur 5th point public void method_name throws Exception{} why some people do that ? – Maveňツ Feb 22 '14 at 07:02
  • An excellent article on the subject: https://weblogs.java.net/blog/carcassi/archive/2009/09/25/simple-guide-checked-exceptions – Duncan Jones Apr 15 '14 at 05:23
  • FileNotFoundException is a checked exception and not a unchecked exception as you mentioned in Q2 by posting a code – Harshana Apr 25 '15 at 08:10
  • It's in the java documentation: https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html – Lorenzo Polidori May 21 '15 at 11:20
  • @BlessedGeek. I think the terminology checked/unchecked exceptions makes perfect sense. Compiler is the one who checks if there is a possibility of an exception. – Vikas May 29 '17 at 18:50
  • Duncan Jones' link is dead, here is a working one: https://community.oracle.com/blogs/carcassi/2009/09/25/simple-guide-checked-exceptions – FLonLon Feb 11 '20 at 11:27

21 Answers21

517

Many people say that checked exceptions (i.e. these that you should explicitly catch or rethrow) should not be used at all. They were eliminated in C# for example, and most languages don't have them. So you can always throw a subclass of RuntimeException (unchecked exception)

However, I think checked exceptions are useful - they are used when you want to force the user of your API to think how to handle the exceptional situation (if it is recoverable). It's just that checked exceptions are overused in the Java platform, which makes people hate them.

Here's my extended view on the topic.

As for the particular questions:

  1. Is the NumberFormatException consider a checked exception?
    No. NumberFormatException is unchecked (= is subclass of RuntimeException). Why? I don't know. (but there should have been a method isValidInteger(..))

  2. Is RuntimeException an unchecked exception?
    Yes, exactly.

  3. What should I do here?
    It depends on where this code is and what you want to happen. If it is in the UI layer - catch it and show a warning; if it's in the service layer - don't catch it at all - let it bubble. Just don't swallow the exception. If an exception occurs in most of the cases you should choose one of these:

    • log it and return
    • rethrow it (declare it to be thrown by the method)
    • construct a new exception by passing the current one in constructor
  4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I?
    It could've been. But nothing stops you from catching the unchecked exception as well

  5. Why do people add class Exception in the throws clause?
    Most often because people are lazy to consider what to catch and what to rethrow. Throwing Exception is a bad practice and should be avoided.

Alas, there is no single rule to let you determine when to catch, when to rethrow, when to use checked and when to use unchecked exceptions. I agree this causes much confusion and a lot of bad code. The general principle is stated by Bloch (you quoted a part of it). And the general principle is to rethrow an exception to the layer where you can handle it.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 38
    Regarding throwing Exception, it isn't always because people are lazy, it's also common that you, when you implement frameworks, let users of the framework be able to throw any exception. You can e.g. check the signature of the Callable interface in JSE – Kaj May 24 '11 at 19:53
  • @Bozho: You answered 1, 2, 4, and 5 and called them 1, 2, 3, and 4. The proper question 3 is hidden in the code block. – Erick Robertson May 24 '11 at 19:54
  • 10
    @Kaj - yes, such general things like Callable, interceptors and the likes are special cases. But in most cases it's because people are lazy :) – Bozho May 24 '11 at 19:55
  • @Bozho, true, it's most often caused by lazy developers. Just wanted to say that there are circumstances when it's ok to have signatures that throw Exception. – Kaj May 24 '11 at 20:02
  • Thank you. One more question when you bubbling up the `exception`, should I bubble up the exact exception or mask it using `Exception`. I writing code on top of some legacy code, and `Exception` being bubbled up all over the places. So according to you, this is a bad behavior? – Thang Pham May 24 '11 at 21:43
  • yes, but if it's already there, you can't do much about it. Let it bubble up. – Bozho May 24 '11 at 21:46
  • @Bozho: one last question I have for you. If I call `File#delete()` and check if `File#delete()` return false, meaning the file delete fail. What exception should I throw there, Bozho? `IllegalStateException` or `IllegalArgumentException` or something else? – Thang Pham May 25 '11 at 13:18
  • I can't give a definitive answer. Perhaps Illegal state. – Bozho May 25 '11 at 13:22
  • 8
    re: 3.1 "log it and return" Do so judiciously. This is very close to eating or hiding and exception. I'd do this for something that does not indicate a problem, that is not really exceptional. Logs get flooded and ignored too easily. – Chris Jul 25 '12 at 14:07
  • 7
    "when you want to force the user of your API to think how to handle the exceptional situation" - you cannot force anyone to think if they do not want to. If they do not want to think, they will write a poor exception block that does nothing at all, or worse, deletes or interferes with critical error information. That is why checked exceptions are a failure. – adrianos Aug 24 '12 at 13:01
  • Don't want to sound harsh, but the definition for "checked exception" in the first paragraph is poor. 'rethrow' as used is vague, and the definition does not identify the specific mechanisms in Java that gives rise to the checked/unchecked debate. Have a look at the defintion by @MichaelBorgwardt He explains points out that a 'checked exception' is identified by type and has implications for method signatures. – Donal Lafferty Dec 12 '12 at 11:44
  • @Bozho - Re: why NumberFormatException is unchecked - there exists a complementary method in java.text.NumberFormat that can be used to parse numbers from strings and that throws a checked exception. This is probably a cleaner approach for handling unknown strings such as user input. That being said for one reason or another it's far less used than the parse* methods (probably because its not in java.lang) – CurtainDog Mar 01 '14 at 23:42
  • @Bozho `NumberFormatException` is unchecked because catch block is suppose to raise programming error but not to recover from the exception. – overexchange Jul 24 '15 at 20:26
  • WTH would anyone argue that checked exceptions are bad news? Please elaborate. – Thomas Sep 08 '15 at 21:08
  • In the linked post I've shared some of the concerns, I think – Bozho Oct 13 '15 at 15:09
  • There's another very good reason to throw Exception from a method--in test code, when you don't expect any checked exceptions to be thrown. Your general test framework can contain a catch (Exception e) { throw new RuntimeException(e) }, and then each test case can just declare that it throws Exception, without having to do the wrapping itself. – Avrom Roy-Faderman Jan 06 '16 at 21:03
  • 3
    @adrianos "...you cannot force anyone to think if they do not want to...." With this line of thinking we could also remove compile errors.... I'm not really targetting you, I have heard this argument time and again and still find it to be the poorest possible explanation for labeling Checked Exceptions as a failure. As a side note, I have seen before such a language where compile (and runtime errors as well actually) were effectively made impossible by desing. That road led to some very dark places. – Newtopian Aug 11 '16 at 17:49
  • @Newtopian Can you name any other compilation error that can be resolved with something so trivial as an empty catch block? – adrianos Aug 17 '16 at 13:43
  • 1
    @adrianos Easy peachy ! try to assign a contrived Cat instance in an equaly contrived Car instance (which do not share the same class hierarchy)... Compiler complains... wrong type... but if I just cast the cat as a car like this car = (Car)cat; boom.. no more complaints from the compiler... Magic ! Compiler still complains ? damn they got smart did they... well just add a cast to Object car = (Car)(Object)cat; and voila ! – Newtopian Aug 17 '16 at 15:24
  • 1
    ... This is obviously a stupid idea and will most certainly cause runtime errors pretty fast. Nobody in their right mind would do this yet, with checked exceptions they do, metaphorically, the same thing. Solving a compiler complaint with an empty catch is pretty much at the same level. No indeed one cannot force anybody to think if they dont want to. I could argue that if one dont think then one should not ne programming either, but I beleive everyone can do something if they want to... – Newtopian Aug 17 '16 at 15:28
  • 1
    ... I'm just saying here that lazyness should never be a valid argument to change a programming language structure. – Newtopian Aug 17 '16 at 15:30
  • @newtopian Yes but nobody ever does anything like the Car example, but useless or harmful catch blocks happen all the time. I agree we should not compromise the language for lazy programmers. But checked exceptions are also a compromise - a failed attempt to try to get lazy developers to do something they didn't want or know how to do, via compiler errors. – adrianos Aug 17 '16 at 15:51
  • 1
    @adrianos API design is all about "forcing" one to do things a certain way, is why we encapsulate objects a certain way rather than another. Fluent builders is a perfect example of this where the returned interface differs depending on the previous call to prevent the programmer from doing anything that would not be supported. Errors is a fact of the programmer's life whether he wants to face it or not. CheckedException is thus far the only way I have seen to properly (that is with compiler support) document what errors can occur should the function be called.... – Newtopian Aug 17 '16 at 16:11
  • 1
    Now I do agree with you, they have been so wildly misused and abused their usefulness is diluted to homeopathic levels. I find nothing pleasant in dealing with how exceptions were implemented in the JDBC API, in my opinion a stellar example of what not to do. But I find nothing pleasant either in using an API that sliently throws exceptions that when caught are so out of context that they are next to useless. CheckedExceptions make my apps more stable, the code easier to uses. As a Chef I'd rather learn to use a sharp knife than replace them all with wood stick because of too many cuts – Newtopian Aug 17 '16 at 16:20
258

Whether something is a "checked exception" has nothing to do with whether you catch it or what you do in the catch block. It's a property of exception classes. Anything that is a subclass of Exception except for RuntimeException and its subclasses is a checked exception.

The Java compiler forces you to either catch checked exceptions or declare them in the method signature. It was supposed to improve program safety, but the majority opinion seems to be that it's not worth the design problems it creates.

Why do they let the exception bubble up? Isnt handle error the sooner the better? Why bubble up?

Because that's the entire point of exceptions. Without this possibility, you would not need exceptions. They enable you to handle errors at a level you choose, rather than forcing you to deal with them in low-level methods where they originally occur.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 3
    Thank you! I occasionally throw exceptions out of my methods because of the crap in crape out principle. I one of the developers on my team wants to enter an invalid xpath expression its up to them to deal with the exception. In the unlikely event they catch an exception and do nothing they will hear about it in code review. – jeremyjjbrown Dec 21 '12 at 04:38
  • 13
    "Anything that is a subclass of Throwable except for RuntimeException and its subclasses is a checked exception." - Your statement is incorrect. Error also inherits Throwable and it is unchecked. – Bartzilla Dec 21 '12 at 19:29
  • Can you elaborate a bit on the design problems it creates? I have a feeling why it would be problematic having all the throws in your method signatures but I am having a hard time arguing against checked exceptions in a bigger context. – Jonas Eicher Nov 14 '13 at 18:40
  • 9
    @JonasEicher: basically, a main advantage of exceptions is that they allow you to choose where in the call stack you want to handle errors, which is often quite high, while keeping the layers in between completely free of error handling artifacts. Checked exceptions destroy exactly that advantage. Another problem is that the distinction checked/unchecked is tied to the exception class which also represents a conceptual categorization of exceptions - mixing two aspects that are not necessarily related at all. – Michael Borgwardt Nov 14 '13 at 21:46
  • 2
    "but the majority opinion seems to be that it's not worth the design problems it creates." - Citation please? – kervin Mar 25 '15 at 17:58
  • 3
    @Bartzilla Yes. For completeness, as the javadoc for `Throwable` says: "Throwable and any subclass of Throwable that is not also a subclass of either RuntimeException or Error are regarded as checked exceptions" – Bart van Heukelom Nov 06 '15 at 13:15
  • "they allow you to choose where in the call stack you want to handle errors, which is often quite high, while keeping the layers in between completely free of error handling artifacts." - this is exactly one of reasons why most Java programs s*ck from user perspective because there is often one single try{}catch(){} high up which just prints "unexpected error", the long callstack and quits. That is very poor error handling in comparison to C code with ifs after every syscall or golang with second error argument. – k3a Jun 02 '19 at 18:48
  • 1
    @k3a: The claim that "most Java programs" have the behaviour you describe is clearly nonsense. And if you're going to judge a language on bad practices, it's still pretty good error handling in comparison to C or golang code that silently ignores error codes. At least the call stack gives any developer investigating the issue a lot of information about what went wrong. – Michael Borgwardt Jun 03 '19 at 13:36
78
  1. Is the above considered to be a checked exception? No The fact that you are handling an exception does not make it a Checked Exception if it is a RuntimeException.

  2. Is RuntimeException an unchecked exception? Yes

Checked Exceptions are subclasses of java.lang.Exception Unchecked Exceptions are subclasses of java.lang.RuntimeException

Calls throwing checked exceptions need to be enclosed in a try{} block or handled in a level above in the caller of the method. In that case the current method must declare that it throws said exceptions so that the callers can make appropriate arrangements to handle the exception.

Hope this helps.

Q: should I bubble up the exact exception or mask it using Exception?

A: Yes this is a very good question and important design consideration. The class Exception is a very general exception class and can be used to wrap internal low level exceptions. You would better create a custom exception and wrap inside it. But, and a big one - Never ever obscure in underlying original root cause. For ex, Don't ever do following -

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.
}

Instead do following:

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.
}

Eating away original root cause buries the actual cause beyond recovery is a nightmare for production support teams where all they are given access to is application logs and error messages. Although the latter is a better design but many people don't use it often because developers just fail to pass on the underlying message to caller. So make a firm note: Always pass on the actual exception back whether or not wrapped in any application specific exception.

On try-catching RuntimeExceptions

RuntimeExceptions as a general rule should not be try-catched. They generally signal a programming error and should be left alone. Instead the programmer should check the error condition before invoking some code which might result in a RuntimeException. For ex:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welcome to my site!);
} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

This is a bad programming practice. Instead a null-check should have been done like -

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

But there are times when such error checking is expensive such as number formatting, consider this -

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));
} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");
}

Here pre-invocation error checking is not worth the effort because it essentially means to duplicate all the string-to-integer conversion code inside parseInt() method - and is error prone if implemented by a developer. So it is better to just do away with try-catch.

So NullPointerException and NumberFormatException are both RuntimeExceptions, catching a NullPointerException should replaced with a graceful null-check while I recommend catching a NumberFormatException explicitly to avoid possible introduction of error prone code.

surendrapanday
  • 530
  • 3
  • 13
d-live
  • 7,926
  • 3
  • 22
  • 16
  • Thank you. One more question when you bubbling up the `exception`, should I bubble up the exact exception or mask it using `Exception`. I writing code on top of some legacy code, and `Exception` being bubbled up all over the places. I wonder if this is the correct behavior? – Thang Pham May 24 '11 at 21:46
  • 1
    This is a very good and important question, edited my answer to include the explanation. – d-live May 25 '11 at 00:50
  • Thank you very much. Would it be possible for you to show me the content of `LoginFailureException(sqle)`? – Thang Pham May 25 '11 at 04:05
  • 1
    I dont have any code for that stuff, I just cooked up the names etc. If you see java.lang.Exception, it has 4 constructors two of them accept java.lang.Throwable. In snippets above I assumed `LoginFailureException` extends `Exception` and declares a constructor `public LoginFailureException(Throwable cause) { super(cause) }` – d-live May 25 '11 at 09:03
  • Best answer about the topic. I think runtime exceptions should not be catched because these exceptions occur due to the lack of good programming. I am completely agree with the part "Eating away original root cause buries the actual cause beyond recovery is a nightmare for production support teams where all they are given access to is application logs and error messages. " . – huseyin Feb 17 '16 at 06:07
20

1 . If you are unsure about an exception, check the API:

 java.lang.Object
 extended by java.lang.Throwable
  extended by java.lang.Exception
   extended by java.lang.RuntimeException  //<-NumberFormatException is a RuntimeException  
    extended by java.lang.IllegalArgumentException
     extended by java.lang.NumberFormatException

2 . Yes, and every exception that extends it.

3 . There is no need to catch and throw the same exception. You can show a new File Dialog in this case.

4 . FileNotFoundException is already a checked exception.

5 . If it is expected that the method calling someMethod to catch the exception, the latter can be thrown. It just "passes the ball". An example of it usage would be if you want to throw it in your own private methods, and handle the exception in your public method instead.

A good reading is the Oracle doc itself: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Why did the designers decide to force a method to specify all uncaught checked exceptions that can be thrown within its scope? Any Exception that can be thrown by a method is part of the method's public programming interface. Those who call a method must know about the exceptions that a method can throw so that they can decide what to do about them. These exceptions are as much a part of that method's programming interface as its parameters and return value.

The next question might be: "If it's so good to document a method's API, including the exceptions it can throw, why not specify runtime exceptions too?" Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.

There's also an important bit of information in the Java Language Specification:

The checked exception classes named in the throws clause are part of the contract between the implementor and user of the method or constructor.

The bottom line IMHO is that you can catch any RuntimeException, but you are not required to and, in fact the implementation is not required to maintain the same non-checked exceptions thrown, as those are not part of the contract.

Community
  • 1
  • 1
Aleadam
  • 40,203
  • 9
  • 86
  • 108
  • Thank you. One more question when you bubbling up the `exception`, should I bubble up the exact exception or mask it using `Exception`. I writing code on top of some legacy code, and `Exception` being bubbled up all over the places. I wonder if this is the correct behavior? – Thang Pham May 24 '11 at 21:42
  • 1
    @Harry I will let people with more knowledge than me to answer that: http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c – Aleadam May 24 '11 at 22:37
10

1) No, a NumberFormatException is an unchecked Exception. Even though you caught it (you aren't required to) because it's unchecked. This is because it is a subclass of IllegalArgumentException which is a subclass of RuntimeException.

2) RuntimeException is the root of all unchecked Exceptions. Every subclass of RuntimeException is unchecked. All other Exceptions and Throwable are checked except for Errors ( Which comes under Throwable).

3/4) You could alert the user that they picked a non-existent file and ask for a new one. Or just quit informing the user that they entered something invalid.

5) Throwing and catching 'Exception' is bad practice. But more generally, you might throw other exceptions so the caller can decide how to deal with it. For example, if you wrote a library to handle reading some file input and your method was passed a non-existent file, you have no idea how to handle that. Does the caller want to ask again or quit? So you throw the Exception up the chain back to the caller.

In many cases, an unchecked Exception occurs because the programmer did not verify inputs (in the case of NumberFormatException in your first question). That's why its optional to catch them, because there are more elegant ways to avoid generating those exceptions.

surendrapanday
  • 530
  • 3
  • 13
dontocsata
  • 3,021
  • 3
  • 20
  • 19
  • Thank you. One more question when you bubbling up the `exception`, should I bubble up the exact exception or mask it using `Exception`. I writing code on top of some legacy code, and `Exception` being bubbled up all over the places. I wonder if this is the correct behavior? – Thang Pham May 24 '11 at 21:42
  • You can either just have your method also throw Exception (which isn't ideal). Or catch Exception and throw a better Exception (like IOException or something). All Exceptions can take an Exception in their constructor as a 'cause', so you should use that. – dontocsata May 25 '11 at 17:59
9

Checked - Prone to happen. Checked in Compile time.

Eg.. FileOperations

UnChecked - Due to Bad data. Checked in Run time.

Eg..

String s = "abc";
Object o = s;
Integer i = (Integer) o;

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at Sample.main(Sample.java:9)

Here exception is due to bad data and in no way it can be determined during compile time.

bharanitharan
  • 2,539
  • 5
  • 32
  • 30
9

Runtime Exceptions : Runtime exceptions are referring to as unchecked exceptions. All other exceptions are checked exceptions, and they don't derive from java.lang.RuntimeException.

Checked Exceptions : A checked exception must be caught somewhere in your code. If you invoke a method that throws a checked exception but you don't catch the checked exception somewhere, your code will not compile. That's why they're called checked exceptions : the compiler checks to make sure that they're handled or declared.

A number of the methods in the Java API throw checked exceptions, so you will often write exception handlers to cope with exceptions generated by methods you didn't write.

AVANISH RAJBHAR
  • 527
  • 3
  • 9
Omer
  • 534
  • 7
  • 19
6

Checked exceptions are checked at compile time by the JVM and its related to resources(files/db/stream/socket etc). The motive of checked exception is that at compile time if the resources are not available the application should define an alternative behaviour to handle this in the catch/finally block.

Unchecked exceptions are purely programmatic errors, wrong calculation, null data or even failures in business logic can lead to runtime exceptions. Its absolutely fine to handle/catch unchecked exceptions in code.

Explanation taken from http://coder2design.com/java-interview-questions/

Jatinder Pal
  • 719
  • 8
  • 3
5

To answer the final question (the others seem thoroughly answered above), "Should I bubble up the exact exception or mask it using Exception?"

I am assuming you mean something like this:

public void myMethod() throws Exception {
    // ... something that throws FileNotFoundException ...
}

No, always declare the most precise exception possible, or a list of such. The exceptions you declare your method as capable of throwing are a part of the contract between your method and the caller. Throwing "FileNotFoundException" means that it is possible the file name isn't valid and the file will not be found; the caller will need to handle that intelligently. Throwing Exception means "Hey, sh*t happens. Deal." Which is a very poor API.

In the comments on the first article there are some examples where "throws Exception" is a valid and reasonable declaration, but that's not the case for most "normal" code you will ever write.

surendrapanday
  • 530
  • 3
  • 13
Tom Dibble
  • 167
  • 1
  • 6
5

My absolute favorite description of the difference between unchecked and checked exceptions is provided by the Java Tutorial trail article, "Unchecked Exceptions - the Controversy" (sorry to get all elementary on this post - but, hey, the basics are sometimes the best):

Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception

The heart of "what type of exception to throw" is semantic (to some degree) and the above quote provides and excellent guideline (hence, I am still blown away by the notion that C# got rid of checked exceptions - particularly as Liskov argues for their usefulness).

The rest then becomes logical: to which exceptions does the compiler expect me to respond, explicitly? The ones from which you expect client to recover.

Thomas
  • 6,291
  • 6
  • 40
  • 69
5

I think that checked exceptions are a good reminder for the developer that uses an external library that things can go wrong with the code from that library in exceptional situations.

Dan Moldovan
  • 371
  • 3
  • 3
3

Why do they let the exception bubble up? Isn't handling the error sooner better? Why bubble up?

For example let say you have some client-server application and client had made a request for some resource that couldn't be find out or for something else error some might have occurred at the server side while processing the user request then it is the duty of the server to tell the client why he couldn't get the thing he requested for,so to achieve that at server side, code is written to throw the exception using throw keyword instead of swallowing or handling it.if server handles it/swallow it, then there will be no chance of intimating to the client that what error had occurred.

Note:To give a clear description of what the error type has occurred we can create our own Exception object and throw it to the client.

JAVA
  • 524
  • 11
  • 23
  • Good point. What it means is to bubble it up to the top most responsible layer that controls the logic flow and oversees the business logic for the application. It would be impossible, for example, for the database layer to communicate to the client that something critical is missing or unresponsive. When it bubbles up to the top most server layer then it is straight forward to refresh the client's view with a critical error message. – Salvador Valencia Sep 21 '16 at 18:18
3
  • Java distinguishes between two categories of exceptions (checked & unchecked).
  • Java enforces a catch or declared requirement for checked exceptions.
  • An exception's type determines whether an exception is checked or unchecked.
  • All exception types that are direct or indirect subclasses of class RuntimeException are unchecked exception.
  • All classes that inherit from class Exception but not RuntimeException are considered to be checked exceptions.
  • Classes that inherit from class Error are considered to be unchecked.
  • Compiler checks each method call and deceleration to determine whether the method throws checked exception.
    • If so the compiler ensures the exception is caught or is declared in a throws clause.
  • To satisfy the declare part of the catch-or-declare requirement, the method that generates the exception must provide a throws clause containing the checked-exception.
  • Exception classes are defined to be checked when they are considered important enough to catch or declare.
surendrapanday
  • 530
  • 3
  • 13
tokhi
  • 21,044
  • 23
  • 95
  • 105
3

I just want to add some reasoning for not using checked exceptions at all. This is not a full answer, but I feel it does answer part of your question, and complements many other answers.

Whenever checked exceptions are involved, there's a throws CheckedException somewhere in a method signature (CheckedException could be any checked exception). A signature does NOT throw an Exception, throwing Exceptions is an aspect of implementation. Interfaces, method signatures, parent classes, all these things should NOT depend on their implementations. The usage of checked Exceptions here (actually the fact that you have to declare the throws in the method signature) is binding your higher-level interfaces with your implementations of these interfaces.

Let me show you an example.

Let's have a nice and clean interface like this

public interface IFoo {
    public void foo();
}

Now we can write many implementations of method foo(), like these

public class Foo implements IFoo {
    @Override
    public void foo() {
        System.out.println("I don't throw and exception");
    }
}

Class Foo is perfectly fine. Now let's make a first attempt at class Bar

public class Bar implements IFoo {
    @Override
    public void foo() {
        //I'm using InterruptedExcepton because you probably heard about it somewhere. It's a checked exception. Any checked exception will work the same.
        throw new InterruptedException();
    }
}

This class Bar won't compile. As InterruptedException is a checked exception, you must either capture it (with a try-catch inside method foo()) or declare that you're throwing it (adding throws InterruptedException to the method signature). As I don't want to capture this exception here (I want it to propagate upwards so I can properly deal with it somewhere else), let's alter the signature.

public class Bar implements IFoo {
    @Override
    public void foo() throws InterruptedException {
        throw new InterruptedException();
    }
}

This class Bar won't compile either! Bar's method foo() does NOT override IFoo's method foo() since their signatures are different. I could remove the @Override annotation, but I want to program against interface IFoo like IFoo foo; and later on decide on which implementation I want to use, like foo = new Bar();. If Bar's method foo() doesn't override IFoo's method foo, when I do foo.foo(); it won't call Bar's implementation of foo().

To make Bar's public void foo() throws InterruptedException override IFoo's public void foo() I MUST add throws InterruptedException to IFoo's method signature. This, however, will cause problems with my Foo class, since it's foo() method's signature differs from IFoo's method signature. Furthermore, if I added throws InterruptedException to Foo's method foo() I would get another error stating that Foo's method foo() declares that it throws an InterruptedException yet it never throws an InterruptedException.

As you can see (if I did a decent job at explaining this stuff), the fact that I'm throwing a checked exception like InterruptedException is forcing me to tie my interface IFoo to one of it's implementations, which in turn causes havoc on IFoo's other implementations!

This is one big reason why checked exceptions are BAD. In caps.

One solution is to capture the checked exception, wrap it in an unchecked exception and throw the unchecked exception.

Blueriver
  • 3,212
  • 3
  • 16
  • 33
  • 2
    Yes, its bad because you said you didn't want to catch it. But to prevent affecting IFOO's signature you will have to. I would rather do that and move on instead of re-balancing all my interfaces signatures in order to avoid catching an exception (just because exceptions are BAD). – Salvador Valencia Sep 21 '16 at 18:28
  • Yeah, I agree. I was a bit unclear about something. I want an exception to propagate, so I can deal with it somewhere else. One solution is catching the InterruptedException and throwing an unchecked exception. i.e. we avoid checked exceptions and pass around unchecked exceptions (even if they only make sense as a wrapper) – Blueriver Sep 22 '16 at 13:27
  • "This, however, will cause problems with my Foo class, since it's foo() method's signature differs from IFoo's method signature". I just tested your idea, and it is possible to compile even if we add `throws InterruptedException` to IFoo's method signature without throwing anything in any implementation. So it does not really causes any problem. If in an interface you make every method signature throw `Exception`, it just gives an implementation the choice to throw or not throw an exception (any exception, as `Exception` encapsulate all exceptions). – Flyout91 Feb 14 '18 at 14:10
  • However I admit that it can be confusing because when you will implement such an inteface and click on something like "Add unimplemented methods", they will be automatically created with the `throw Exception` clause in their signature, even though your implementation will not throw anything or may be a more specific exception. But I still feel like it is a good practice to always throw Exception for an Interface's method because, again, it gives the user the choice to throw or not throw anything. – Flyout91 Feb 14 '18 at 14:21
  • This misses the entire point. The purpose of an interface is to declare the contract a client requires to be satisfied. This can include failure scenarios that it is able to handle. When an implementation encounters an error, it should map that error to the appropriate abstract failure declared by the client interface. – erickson Dec 11 '18 at 16:43
2

Here is a simple rule that can help you decide. It is related to how interfaces are used in Java.

Take your class and imagine designing an interface for it such that the interface describes the functionality of the class but none of the underlying implementation (as an interface should). Pretend perhaps that you might implement the class in another way.

Look at the methods of the interface and consider the exceptions they might throw:

If an exception can be thrown by a method, regardless of the underlying implementation (in other words, it describes the functionality only) then it should probably be a checked exception in the interface.

If an exception is caused by the underlying implementation, it should not be in the interface. Therefore, it must either be an unchecked exception in your class (since unchecked exceptions need not appear in the interface signature), or you must wrap it and rethrow as a checked exception that is part of the interface method.

To decide if you should wrap and rethrow, you should again consider whether it makes sense for a user of the interface to have to handle the exception condition immediately, or the exception is so general that there is nothing you can do about it and it should propagate up the stack. Does the wrapped exception make sense when expressed as functionality of the new interface you are defining or is it just a carrier for a bag of possible error conditions that could also happen to other methods? If the former, it might still be a checked exception, otherwise it should be unchecked.

You should not usually plan to "bubble-up" exceptions (catch and rethrow). Either an exception should be handled by the caller (in which case it is checked) or it should go all the way up to a high level handler (in which case it is easiest if it is unchecked).

rghome
  • 8,529
  • 8
  • 43
  • 62
2

Just to point out that if you throw a checked exception in a code and the catch is few levels above, you need to declare the exception in the signature of each method between you and the catch. So, encapsulation is broken because all functions in the path of throw must know about details of that exception.

Zoran Pandovski
  • 2,312
  • 14
  • 24
2

In short, exceptions which your module or modules above are supposed to handle during runtime are called checked exceptions; others are unchecked exceptions which are either RuntimeException or Error.

In this video, it explains checked and unchecked exceptions in Java:
https://www.youtube.com/watch?v=ue2pOqLaArw

Pang
  • 9,564
  • 146
  • 81
  • 122
Ozgen
  • 1,072
  • 10
  • 19
1

All of those are checked exceptions. Unchecked exceptions are subclasses of RuntimeException. The decision is not how to handle them, it's should your code throw them. If you don't want the compiler telling you that you haven't handled an exception then you use an unchecked (subclass of RuntimeException) exception. Those should be saved for situations that you can't recover from, like out of memory errors and the like.

mamboking
  • 4,559
  • 23
  • 27
  • um. if NumberFormatException is a checked exception, like you say, isn't it contradicting the fact that it is [inherited from RuntimeException](http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/NumberFormatException.html)? – eis Aug 13 '12 at 13:26
  • Sorry, I wasn't very clear. I was referring to the FileNotFoundException not the NumberFormatException. Based on his #2 & #4, it seemed like he thought that Checked vs. Unchecked was based on how you handled the exception after catching it. Not how it was defined. – mamboking Aug 13 '12 at 14:23
0

Checked Exceptions :

  • The exceptions which are checked by the compiler for smooth execution of the program at runtime are called Checked Exception.

  • These occur at compile time.

  • If these are not handled properly, they will give compile time error (Not Exception).
  • All subclasses of Exception class except RuntimeException are Checked Exception.

    Hypothetical Example - Suppose you are leaving your house for the exam, but if you check whether you took your Hall Ticket at home(compile time) then there won't be any problem at Exam Hall(runtime).

Unchecked Exception :

  • The exceptions which are not checked by the compiler are called Unchecked Exceptions.

  • These occur at runtime.

  • If these exceptions are not handled properly, they don’t give compile time error. But the program will be terminated prematurely at runtime.

  • All subclasses of RunTimeException and Error are unchecked exceptions.

    Hypothetical Example - Suppose you are in your exam hall but somehow your school had a fire accident (means at runtime) where you can't do anything at that time but precautions can be made before (compile time).

Varun Vashista
  • 157
  • 1
  • 5
-1

If anybody cares for yet another proof to dislike checked exceptions, see the first few paragraphs of the popular JSON library:

"Although this is a checked exception, it is rarely recoverable. Most callers should simply wrap this exception in an unchecked exception and rethrow: "

So why in the world would anyone make developers keep checking the exception, if we should "simply wrap it" instead? lol

http://developer.android.com/reference/org/json/JSONException.html

Slawomir
  • 3,194
  • 1
  • 30
  • 36
  • 4
    Because it is only most callers, not all callers, that should wrap and rethrow. The fact that the exception is checked means the caller has to think about whether they are one of the "most" callers, or one of the minority that can and should handle the exception. – Warren Dew May 29 '14 at 15:41
  • 1
    If you like checking errors for every call you make, "go back" to C. Exceptions are a way to separate normal program execution from abnormal, without polluting your code. Exceptions ensure you cannot ignore an error silently _at some level_. – Slawomir May 30 '14 at 15:57
-2

All exceptions must be checked exceptions.

  1. Unchecked exceptions are unrestricted gotos. And unrestricted gotos are considered a bad thing.

  2. Unchecked exceptions break encapsulation. To process them correctly, all the functions in the call tree between the thrower and the catcher must be known to avoid bugs.

  3. Exceptions are errors in the function that throws them but not errors in the function that processes them. The purpose of exceptions is to give the program a second chance by deferring the decision of whether it's an error or not to another context. It's only in the other context can the correct decision be made.

shawnhcorey
  • 3,545
  • 1
  • 15
  • 17