Other than grouping similar exception types, what are the other advantages of handling multiple exception in one catch block over handling it using base Exception class?
Why to prefer this :
try{
//some code
}
catch(FileNotFoundException e1 | IOException e2){
}
Over this (This is less verbose) :
try{
//some code
}
catch(Exception e){
}
Catching generic Exception will also catch NullPointerException, IndexOutOfBoundsException and other exceptions that you generally don't want to catch. By catching the specific exceptions you want to handle you can avoid these situations.
Well it's more about being efficient and effective in your exception handling, you've got quite a few ways of doing things like this. Also keep in mind that when you're working on a project big or small depending on what you're doing attempting to use some thing like
try{
}(catch Exception e);
on a program (for example) using Encryption you'll get a ton of errors, like
NoSuchAlgorithmException
InvalidKeyException
And much more because that base Exception can't handle them.
When you use a compiler and each one is different... but in general they will all give you some form of a warning basically telling you " Hey Exception e wont handle this"
You'll also see that you'll have the ability to do things like this.
public setStringExample(string example) throws IOException, Exception, NullPointerExcetptiopn {
}
Java in a lot of ways forces you to account for most things which isn't really a bad thing I guess lol..
TL;DR The overall point I'm trying to make is that Exception handling should be done properly and efficiently which is learned over time, don't try to catch some thing that isn't their and don't try to avoid catching some thing that probably will be!
The two pieces of code are not equivalent.
The first one catches ONLY FileNotFoundException, IOException and their subclasses1.
The second one catches the above PLUS all other checked exceptions AND all unchecked exceptions (apart from Error and its subclasses). So:
You would be catching a whole bunch of exceptions that are typically a result of programming error; e.g. null pointers, problems with indexing and so on.
You are effectively "turning off" the checked exception mechanism which would give you a compile time error if you forgot to handle some checked exception; e.g. SQLException. Now at this point in time your code probably doesn't throw any checked exceptions apart from the ones you are catching (in version #1). But what happens if you modify the code to call some method that (say) throws SQLException:
With version #1 ... compilation error. Ooops, but you can fix that.
With version #2 ... no compilation error. Lets hope that your unit and systems tests are good enough to pick up the problem.
So, to answer your question ...
Why to prefer [version #1] ... over [version #2] (This is less verbose) :
You should prefer the one that is correct, not the one that is less verbose. The second version will catch exceptions that you (probably) don't intend to be caught, which makes it incorrect.
Prefer version #1.
1 - Note that FileNotFoundException is a subclass of IOException so you could rewrite version #1 to catch IOException only. If "verbosity" is your main focus, then catching BOTH IOException and FileNotFoundException is verbose.
Related
I frequently come across the same problem. At the very core of my Java Application, I have methods that throw an exception which cannot be handled by any method caller. I have to bubble those exceptions up to the main method. All those exception summarize so I have many throws statements on higher levels of my Application.
E.g. I have a NodeJsManager.java class at the core of my application:
public class NodeJsManager {
public static void startNodeJs() throws ExecuteException {
// Code to start NodeJs Server goes here
}
}
To start the NodeJs Server, I have to execute something on command line. I can do that with the apache class org.apache.commons.exec.CommandLine. But it throws an ExecuteException, if the execution exited with an error code. Without NodeJs being started my application is useless. No method can catch this exception, it is just a requirement for my application to work. So the exception will bubble up almost the whole application lifecycle. I have other Managers that do the same (a ConfigurationManager that throws an exception, if the config path is wrong). All together it summarizes in many throws statements at every single method on a higher level where I don't even remember the cause of that exception.
How would you handle that problem? I must do something completely wrong because I can't find similar posts that describe my problem!
Regards
Mike
Update
I just unearthed my good old Effective Java book. The Author (a Java architect at Google) wrote the following about Exceptions:
... use checked exceptions for recoverable conditions and runtime
exceptions for programming errors.
...
If it isn't clear whether recovery is possible, you're probably better off using an unchecked exception ...
In my case it is clearly not recoverable, so throwing a runtime exception is the way to go. I always thought runtime exceptions should be prevented, this changes my point of view about exceptions in Java.
One possible approach is to deal with the Exception as close as possible to where it originated, where you have enough information to make a decision on what to do.
As you said if you have all the Exceptions caught at the highest level possible you are losing the context which is really important, because that gives information on why and how the problem occurred (and hopefully a few ways to fix it).
You said for example that your application without a NodeJS server is useless, then probably a way of doing this would be to have the NodeJSManager (if such a thing exists :D, I'm guessing) to not throw, but prevent the application from starting at all, something like
NodeJSManager nodejsManager = new NodeJSManager();
boolean succeeded = nodejsManager.tryToStart();
if (!succeeded) {
// guard, it's useless to proceed
// cleanup and exit
}
I called that method tryToStart because it can happen that the server does not start, you are dealing directly with the executables and the file system so I would say this is not so exceptional any more (but probably this is just a matter of taste).
What's important IMHO is that you specify your application start up as a series of checks, for example the node and the configuration ones, without having to deal with Exceptions to handle the flow of your code.
I don't like checked Exceptions. What I use to do (but is NOT a nice solution) is to catch the checked Exception and re-throw it as a Runtime Exception this way:
catch (ExecuteException e) {
throw new RuntimeException (e);
}
The checked Exception "e" is passed as an parameter to RuntimeException. This way, I convert a checked into an unchecked exception. But as I said, is not a nice solution and it may cause more debugging problems that it solves. When an Exception is "checked" it tends to be because the error described is "serious".
One solution would be to create your own, more general exception class that will extends Exception and wrap unhandled exceptions as causes into your own exception. This way you can at least reduce some exceptions from methods signatures. example:
Create new class StartupException or ConfigurationException and throw it with the main exception after catching it as cause during startup phase.
Moreover if you would make StartupException extends RuntimeException) you would not have to declare such exception.
Another way would be to wrap everything into RuntimeException
If abowe does not suit your needs than this is probably design flaw, (if you really cannot handle it) that you will have to deal with it.
I'm trying to understand checked exceptions in Java and have the following query.
Is the following correct: If a method has the potential to throw a checked exception, of any type, that exception must either be
declared using the throws keyword, or
caught by the respective method.
If the above is correct, does this mean that I need to understand every single checked exception that is built in to Java so that I know whether my method will have the potential to throw that exception? Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
If the above is correct, does this mean that I need to understand every single checked exception that is built in to Java [...]?
Yes, your statements are correct, but no one expects you to know of all potential checked exceptions when programming. And you don't have to if you have a compiler, or better, an IDE at hand.
Either you go back and forth between compiler output and code as you suggest in your question, or you install an IDE such as Eclipse which gives you direct notifications if you violate the rule:
does this mean that I need to understand every single checked exception that is built in to Java
I assume you are using some IDE (eg. Eclipse) - if not, you should get one ASAP.
Then, the IDE pretty much continuously compiles the code, so when there's a problem, you will get a red underline near it, and a tooltip bubble telling you what's wrong - eg "Missing throws".
Therefore, your second assumption is basically correct, it just happens behind the scenes:
Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
So no, you don't need to learn all the exceptions.
Also, all checked Exceptions extend Exception, so if you have access to the source, you can check what they are based on. Non-checked exceptions extend RuntimeException.
Rule of thumb: If it's something with I/O, it's usually checked. That's the most common type of exception you will encounter.
whenever you use a method (whether your own or In-built) if you closely follow its method signature, if the method throws some exception you need to throw/handle it explicitly in your code
In this way you will not need to memorize all the exceptions and you will know which exceptions to handle where.
To make life easy use some IDE like eclipse
hope this helps!
Good luck!
If the above is correct
It is...
[...] does this mean that I need to understand every single checked exception that is built in to Java so that I know whether my method will have the potential to generate that exception? Or should I just attempt to compile my code and then amend my code based on the compile-time errors?
Use an IDE! You don't need to intimately know ALL of them.
What you do want to check however is the hierarchy (ie, check the javadoc! That should be a Pavlovian reflex); since exceptions are classes, they inherit one another and, for instance, FileSystemException is a portmanteau exception of java.nio.file to signal a filesystem related problem and it inherits IOException. Catch it before IOException if you want to treat it specially.
As a general rule, catch more specific exceptions first.
Also, DO NOT catch Exception. Never. The problem is that RuntimeException, which is the base exception for unchecked exceptions, inherits Exception, meaning that if you catch Exception you catch all unchecked exceptions. You want to rethrow unchecked ones:
try {
something();
} catch (RuntimeException unchecked) {
throw unchecked;
} catch (Exception e) {
// deal with e
}
Yes you need to know every exception..however if u know super class of that exception than you u don't need to know the subclass of it...for e.g..FileReader throws a exception called FileNotFoundException Since FileNotFoundException is a subclass of IOException, we can just specify IOException in the throws list and make the above program compiler-error-free.
I'm validating a xml against a xsd, and I'm finding that there are many cases where exceptions have to be handled.
I believe these are called checked exceptions in java?
SchemaFactory sf = ....
Schema schema = sf.newSchema(...) // SAXException has to be handled
Validator validator = ...
validator.validate(xmlFile); // IOException has to be handled again
How should I be writing this code block?
Do I use try/catch nested inside a try/catch?
try {
SchemaFactory sf = ....
Schema schema = sf.newSchema(...) // SAXException has to be handled
Validator validator = ...
validator.validate(xmlFile); // IOException has to be handled again
} catch (SAXException e) {
// handle SAX error
} catch (IOException e) {
// handle IO error
}
Do I use try/catch nested inside a try/catch?
IMO, no.
try {
//...
} catch(SAXException e) {
//handle SAXException
} catch(IOException e) {
//handle IOException
}
I think the code looks cleaner like that than with nested try/catch.
How should I be writing this code block?
It depends on whether you need to handle the exception right there, in which case you use try/catch, or if need the caller to handle the exception, in which case you should propagate it to the caller by using the throws clause.
public void validateXml() throws SAXException, IOException {
//...
Actually you are not supposed to handle checked exceptions if you don't have any recovery strategy.
Do you have another schema in case the one you use raise a Sax exception?
Do you have another validator in case the one you use raise an IO exception?
Any other recovery possible for these exceptions?
If you don't, you should probably wrap that exception inside a Runtime (unchecked) exception and let it be thrown to the top layer (where it will be catched). Eventually you can add an extra message in the wrapper class if needed to understand the problem.
Unless your program can work correctly without this sax schema (in this case you would catch Exception, to also be able to catch runtime exceptions), or your program have a recovery strategy, you are not supposed to catch an exception without rethrowing it.
If your recovery strategy fail, you can also wrap the recovery exception into an unchecked exception to let the top layer handle it (log + error 500 or something like that).
This is the principle of fail-fast.
Note that in Java there is a big controversy that exist for years about checked VS unchecked exceptions. Many influent people in Java really think introducing checked exceptions was an error.
The main reasons are:
People are lazy and tend to catch the exception in the wrong place, so that they are not bothered anymore.
People doesn't follow the sun recommandations: they throw checked exceptions just to "give a warning" at compile time for the client side of the API.
People tend to think that only methods declaring checked exceptions can raise exception, while ANY code/method CAN throw exceptions. You are not supposed to catch exception ONLY WHEN THE COMPILER SAYS SO: YOU HAVE TO THINK WHERE IT'S APPROPRIATE TO CATCH.
Are kinda agree with Bruce Eckel:
I think the problem is that this is an untested assumption we're
making as language designers that falls into the field of psychology.
You can find many links on that subject. Many java developers are not aware of this, but also many mature frameworks now mainly use unchecked exceptions (Spring, EJB3...).
Also people doing C# (no checked exceptions) and Java tend to think it's better when there are no checked exceptions.
So you may do:
try {
your code here
} catch (Exception e) {
throw new RuntimeException("optionnal message",e);
}
You can eventually use a custom runtime exception if you think it will be useful
Sun sources:
http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
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.
http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html#11.5
The class Exception is the superclass of all the exceptions that
ordinary programs may wish to recover from.
Bruce Eckel (Thinking in Java book):
http://www.mindview.net/Etc/Discussions/CheckedExceptions
"Ignorable" in the previous paragraph is the other issue. The theory
is that if the compiler forces the programmer to either handle the
exception or pass it on in an exception specification, then the
programmer's attention will always be brought back to the possibility
of errors and they will thus properly take care of them. I think the
problem is that this is an untested assumption we're making as
language designers that falls into the field of psychology. My theory
is that when someone is trying to do something and you are constantly
prodding them with annoyances, they will use the quickest device
available to make those annoyances go away so they can get their thing
done, perhaps assuming they'll go back and take out the device later.
I discovered I had done this in the first edition of Thinking in Java:
...
} catch (SomeKindOfException e) {}
Is there any reason for not converting the following code
try {
// Do something
} catch (XException e) {
e.printStackTrace();
} catch (YException e) {
e.printStackTrace();
} catch (ZException e) {
e.printStackTrace();
}
to this:
try {
// Do something
} catch (Exception e) {
e.printStackTrace();
}
I know the 2nd one catches all kinds of Exceptions, and I don't mind that. And let's say I want to handle all exceptions in the same way. Is the performance difference considerable?
The Java try/catch mechanism has been so highly tuned in successive JVM's that their performance is never something you should be explicitely worried about. Rather, you should be coding those blocks according to whether you need to handle the caught error scenarios in different ways. In your example you are just printing a stack trace so it is not beneficial to catch the specific errors - but your use case will actually determine wether you should be rolling up or down for these try/catch blocks.
This separation is only because you would be able to perform different task for different exceptions. Like if you receive parse exception and you get IO exception so you would know exactly what to do with each exception.
In newer version this blocks has been minimized with multiple exception in on block which will help the coder and increase the readability. e.g.
try {
// Do something
} catch (XException | YException | ZException e) {
e.printStackTrace();
}
I wouldn't worry about performance at the moment (unless you know it's a real issue).
You may want to convert for readability (if the same action is performed for each type of excpeption), but don't forget that catching Exception will catch lots of other stuff besides XException, YException, ZException. Is there a useful base class for those, and can you catch that instead ?
Occasionally you may want to perform different actions on different exceptions.
Even if you don't you still help other programmers see the complete picture rather than hiding it in one big Exception; which also happens to catch all Runtime exceptions.
The main reason you catch the exceptions separately is you may want to do something different based on which exception has been thrown. For example when parsing a file, you may want to throw a FileNotFoundException, or an IndexOutOfBounds exception. One tells you you cannot find the file to parse, while the other tells you there was a problem during the parse itself. It's much more informative to handle these separately as they are entirely different problems. For example the end user could receive different error messages based on the exception thrown.
There is a difference in catching RunTimeExceptions like NullPointerException. Those will be caught in the second case but not in the first.
In the vast majority of situations you want exception handlers to be as specific as possible so that your code is resilient and adopts an appropriate recovery strategy in the event that an exception occurs. Taking a general approach to exception handling is unwise as the handler must react to any exception possibility which this can result in code being more error-prone when unexpected exceptions are caught which the handler was not intended to handle. In essence exception handlers with the clause catch (Exception e) is the lazy approach.
In my experience the motivation for placing an exception handler around a block of code is to catch a specific exception or set of exceptions. Therefore at the time of conception you know the exceptions you want to catch anyway, why generalise and use the Exception class?
I'd advise reading two things to gain appreciation for specific exception handling:
Effective Java Second Edition - Joshua Bloch : Chapter 9
The Java tutorial on Exceptions : Advantages of Exceptions
IMHO it is just a question of handling all errors the same way or some in a different way.
First one is useful when you want to handle different exceptions in different ways and in second case you are handling all exception in same way. Use second way when you perfectly don't know which exception will occur and if you know you can use the first one.
Not much difference from a technical perspective. The second version will catch all XYZ exceptions plus any RuntimeException that may be thrown in the try block. Check, if that is OK.
If the catch handlers all do the same for any thrown exception, then I see no problem with grouping them. Although it is not very common (in production code) to have equal catch handlers, usually they do different things or log different messages.
Reason is to handle different exceptions for ex. for a sql exception you may want to rollback the transaction but for a io exception for an unfound file u may want to create that file etc.
If we consider the performance there is no difference between handling in one catch block or with multiple.
exception can occurs for many reasons
A file that needs to be opened cannot be found (fileNotFoundException or InputStreamExcep)
A user has entered invalid data.
network connection has been lost or the JVM has run out of memory.
Types of exceptions:
Three Kinds of Exceptions are:
Checked exception:
A checked exception is an exception that a user error or a problem which is not foreseen by the programmer.
Example:if a file is to be opened, but the file is not found, an exception occurs. These exceptions cannot be ignored at the time of compilation.
Unchecked exceptions: A runtime exception is an exception that occurs that probably ignored by the programmer.It is also known as runtime exceptions.these are ignored at the time of compliation.
Errors: problems that arise beyond the control of the programmer.
Example, if a stack overflow occurs, an error will arise. These are ignored at the time of compilation.
Catching Exceptions:
Byusing try/catch, we can handle the exception.try block is placed around the code that might generate an exception.
A catch statement involves declaring the type of exception you are trying to catch. If an exception occurs in protected code, the catch block (or blocks) that follows the try is checked. If the type of exception that occurred is listed in a catch block, the exception is passed to the catch block much as an argument is passed into a method parameter.
Multiple catch Blocks:
A try block can be followed by multiple catch blocks.
At what point would you create your own exception class vs. using java.lang.Exception? (All the time? Only if it will be used outside the package? Only if it must contain advanced logic? etc...)
I think you need to ask yourself a slighly different question "What advantage does creating a new exception give me or developers who use my code?" Really the only advantage it gives you or other people is the ability to handle the exception. That seems like an obvious answer but really it's not. You should only be handling exceptions that you can reasonably recover from. If the exception you throw is a truly fatal error why give developers a chance to mis-handle it?
More in depth discussion: Custom exceptions: When should you create them?
Reason one:
Need to catch specific stuff. If calling code needs to deal with a specific exceptional condition, you need to differentiate your Exception, and Java differentiates exceptions with different types, so you need to write your own.
Basically, if someone has to write:
catch(ExistingException e) {
if({condition}) {
{ some stuff here}
}
else {
{ different stuff here}
}
}
You probably want to write a specific extension; catch Exception matching is clearer than conditionals, IMHO.
Remember: your new Exception can be a subclass of RuntimeException
Reason two:
API consolidation. If you write an interface and you have several implementations, it's possible that they will call different APIs with a whole bunch of different non-RuntimeExceptions thrown:
interface MyInterface {
void methodA();
}
class MyImplA {
void methodA() throws SQLException { ... }
}
class MyImplB {
void methodA() throws IOException { ... }
}
Do you really want MyInterface.methodA to throw SQLException and IOException? Maybe then it makes sense to wrap the possible exceptions in a custom Exception. Which again can be a RuntimeException. Or even RuntimeException itself...
I believe that:
catch (Exception e) {
...
}
... is an antipattern that should be avoided. You might want one centralized broad catch somewhere in your application, to log an error and prevent the whole application from terminating - but having them scattered around willy-nilly is bad.
Why:
try {
if(myShape.isHidden()) {
throw new Exception();
}
// More logic
} catch (Exception e) {
MyApp.notify("Can't munge a hidden shape");
}
So you try this, and due to a coding error, myShape is null. A NullPointerException gets thrown when the runtime tries to derefence myShape. This code reports a hidden shape, when it should be reporting a null pointer.
Either make your own exception, or find a suitably specialized exception in the API. It's not as if extending Exception or RuntimeException is onerous.
When I want to treat my exceptions differently from everybody else's. If I want to catch mine and propagate everyone else's, or if I want to catch someone else's and propagate mine, or if I want to catch both but treat them differently, then I will define a separate class for my exceptions. If I want to treat them all the same, either by propagating both or by catching both (and doing the same thing either way with the caught exceptions), the I will use the standard class.
IF there is an existing Exception with the language runtime or libraries, use it ELSE create your own, document it well and that should work in 99% of the cases.
Software captures meaning.
There are almost no reasons for throwing an existing exception: the JVM already does that for you. Your version of their exception isn't really accurate and throwing "Exception" isn't meaningful, either.
You might have a DataFormatException because of a parsing algorithm you wrote. This, however, is rare.
When your program encounters an exceptional situation, it's almost always unique to your program. Why force-fit your exceptional situation into an existing exception? If it's unique to your program, then... well... it's unique. Name it that way.
Do not, however, provide a unique exception class for each unique message. One exception class can have many variant messages and supporting details.
The Python rule of thumb, translated to Java, is to define any unique exceptions at the package level. [In Python, they suggest exceptions at the "module" level, something that doesn't precisely translate to Java.]
Start always by using the common exception classes and then when a need appears to handle it specially, change it.
When creating a method first time, just let exceptions go through.
If there are exceptions that must be handled, those can either be just defined in throws or wrapped to some runtime exception or wrapped own throws exception. I prefer runtime exceptions in many cases. Defining throws definition should be avoided until there is a need for it from API point of view.
Later when a need appears to do specific handling for an exception in some caller, come back and create new exception for it.
The point is to avoid doing extra work before knowing what is needed.
I can't imagine specifically throwing a java.lang.Exception if some object/class/method had a problem. It's too generic - if you're not going to create your own Exception class, seems to me like there ought to at least be a more specific Exception-type in the API.
I would use the exceptions from the Java API when the exception relates to the API. But if an exceptional situation arises that is unique to my own API then I will create an Exception for it. For example if I have a Range object with two properties min and max and the invariant min <= max then I will create an exception InvalidRangeException.
When I am writing code this helps because I know if the exception originates because I violated one of my own conditions or its something from the Java API.
In most cases it doesn't make sense to create your own exception class.
There is a tendency in novice programmers to create their own exception class just so they can use a name that is more indicative of the type of error. So you'll find classes like FTPInitializationException, DAOFactoryException etc. even though such exceptions are not being handled differently than standard exceptions. This is clearly an anti pattern that should be avoided.