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.
Related
Why do we have to use in catch, Exception if this class includes errors (like java virtual machine exception) or exceptions like NullPointerException...these exceptions are unchecked exception. I found examples on internet, but I don't understand why it is necessary to use Exception in this code. Why we don't catch exception that are bound to hibernate framework?
try{
Session session = sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.eq("pk.stud.id",idStude));
carte = (List<StudentC>) criteria.list();
}catch(Exception e){
System.out.println("\n"+e.toString()+" "+e.getMessage()+"\n");
}
System.out.println("\nENTER UnivDAO \n");
Your hibernate code is accessing database and can update/delete/lock records.
If your code will throw unchecked exception without catch the database connection can remain open and may cause a connection leak or even lock database record(s).
Also you may have a catch in high level function that will may handle such exception the wrong way, e.g. expect some different parameter is null
The point is that such code can probably throw a whole set of different checked exception types.
And instead of asking you to catch these 5 different exceptions the authors of that API decided to reduce the operation to say "throws Exception". That reduces effort on both sides - the throws list is easier to manage now. But the downside is that you lose a bit of information on what is really going on.
This is a common practice. Sometimes it is a good idea, sometimes not.
It's not neccessary to catch any exceptions around that code. A lot of the examples catch exceptions just to demonstrate which exceptions are thrown. That example probably leaves carte set to null, or an empty list, after the try/catch block which will only cause further exceptions to be thrown, or invalid results to be returned. Instead, the exception should be thrown, and handled at a higher level, probably at the request level.
If the query results are unavailable, then it doesn't really matter whether it's because of the database being down, or a programming error. The response is usually the same. An error message is sent to the user, or default values are used. The error is logged, and you move on to the next request.
Also in the example, calling System.out or e.getMessage() means we lose a lot of information about where or when the exception occurred. It's not meant to be used in real code, instead the exception should be sent to a logger.
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.
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) {}
What is the use of rethrowing checked and unchecked exceptions?
If you want to execute some code when a problem happens without hiding the problem.
For example, let's say you want to rollback changes if an exception occurs while writing to a database:
try {
writeToDatabase();
} catch(Exception ex) {
rollbackChanges();
}
If you use this code, the calling function will never find out that an exception occurred.
Instead, you should write
try {
writeToDatabase();
} catch(Exception ex) {
rollbackChanges();
throw ex;
}
To be somewhat blunt: to use exception handling.
Consider this, before exceptions (or, before a developer understands how to properly use exception handling) programmers would return error codes like -1 or null if something 'went wrong'. With that in mind, how would you tell something several methods back that it failed (eg: some low level IO method in a large API failed)? You could either string a lot of return nulls/ or -1's together, or just throw an exception so that it migrates back up to somewhere where it should be caught, even the JVM itself if need be as this exception might something you cannot recover from.
So basically, you would rethrow an exception if you are unable to write catch logic that can truly recover from the thrown exception. This is often the case in Java because Java forces you to catch almost all of its Exceptions since most everything is a checked exception.
As for rethrowing checked vs unchecked... Often times I will throw a new unchecked exception (RuntimeExpcetion) from inside a checked exception back up to the container when doing J2EE applications. The container has a default way of handling exceptions and showing the user a default error page. This comes from the Aspect Oriented paradigm. I also wrote about how to do this here.
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.