Java catch exception design and performance - java

I want to understand something about catching exceptions.
If I don't want my application to crash while an exception occurs and have no idea what exception will be thrown, then my way of handling the exception in the code is something like this:
public static void main(String[] args) {
try {
// all my code to new StarGAte with a lot of threads and classes
} catch (Exception e){
//Something went wrong (kill the dev!)
}
}
are there any performance issue in my code with try/catch block?
Is there a better way to handle exceptions?

are they any performance issue with cover all my code with try/catch?
No. If no exceptions are thrown, the exception handling code is never run.
there is a better way to do design exception handling?
Don't catch Exception unless a method you call actually throws Exception. Catch specific checked exceptions, and RuntimeException if you want to be sure.

Exceptions should only be used for error handling. As such they should be rarely executed in your code and their performance will be acceptable most of the time.
Here are some tips on handling exceptions taken from my post Exceptions Guidelines
Don’t catch top-level exceptions
Don’t catch the top-level exception classes such as Throwable, Exception or RuntimeException directly in your API, unless you really know you need to and you are at the very top of your code base (your main method and top level server/daemon code). These exception classes contain many unrecoverable exceptions that can’t be handled safely. This is especially true for the Throwable class which also catches Error exceptions that the JVM might throw such as out of memory exceptions. Catching these exceptions and continuing to run your application may result in data corruption and undefined behavior.
Make sure that your catch() statements are ordered correctly from most specific to most general. You can use multi-catch statements to group exceptions that need the same treatment like logging an error:
catch( Exception1 | Exception2 | Exception3 e) {
logger.log( "Bad Exception: " + e.getMessage(), e );
}
Use the common parent if multiple exceptions can be thrown and handled the same way. For example catching IOException will catch automatically FileNotFoundException because it inherits form IOException.
Avoid catching the Throwable class! Bad things will happen when you start catching unrecoverable JVM exceptions.
Don’t use exceptions for flow-control
It slows down your code and makes it less maintainable. It is considered very bad practice.

Related

Does every exception have an required try-catch?

A simple question and I can't find the answer for it.
Is it required to every exception in Java to use a try-catch? Or is it only for the FileNotFoundException?
A lot of exceptions (IndexOutOfBoundException, ArithmeticException, IlligalArgumentException, NullPointerException) are saying that they didn't need an Exception, but FileNotFoundException does)... and I can't find the answer which do and which doesn't need try-catch.
It's not absolutely required to have a try/catch block for your exceptions. Instead, you can throw them to someone who is able to handle the exception properly.
There are 2 kinds of exceptions: Checked and Unchecked. A Checked exception can be considered one that is found by the compiler, and the compiler knows that it has a chance to occur, so you need to catch or throw it. For example, opening a file. It has a chance to fail, and the compiler knows this, so you're forced to catch or throw the possible IOException.
An Unchecked exception can be considered one that has a chance of occurring, but based on your code, the compiler doesn't know. In other words, it's a programming error. For example, if you're taking user input and expect a number, and the user enters something you didn't expect, such as a string, your program would throw a NumberFormatException. You can predict these scenarios and put try/catch to try and avoid them before they occur. Very rarely seen is a person adding a throws NullPointerException or throws NumberFormatException (or throwing any other Unchecked exception, for that matter). It's allowed, but explicitly creating that exception is weird and most people would say that it's bad coding style.
Note that all Checked suggestions must be caught or thrown to something that can handle it; if you don't do it, your program won't compile. If you throw it to something that can't handle it, then your program will likely crash if it occurs.
Also note that an unchecked Exception (eg: one that occurs during runtime, usually via bad user input or whatnot) will also usually crash your program. Thus, it's usually a good idea to use try/catch when something can potentially go wrong, but you don't have to.
Also interesting to note is that while Checked exceptions are subclasses of Exception and Unchecked exceptions are subclasses of RuntimeException, RuntimeException itself is a subclass of Exception. That means that if you really wanted to, a single try {} catch (Exception e) {} will catch every single exception your program could possibly throw. Granted, this is considered a horrible way to deal with exceptions, and you should catch each one separately so that you can handle them separately. Please try not to use it.
No, not every exception requires a try-catch. Every checked exception requires a try catch. For example, a NullPointerException is an unchecked exception, so it does not require a try-catch, whereas a FileNotFoundException is checked, so it does require one. You can also add "throws" to the method signature and thus avoid needing a try-catch.
Read:
https://docs.oracle.com/javase/tutorial/essential/exceptions/
Basically checked Exceptions need to be handled or thrown
Unchecked Exceptions and Errors may be handled or thrown (although handling Error is in general considered bad practise).
Checked exception is everything that inherits from java.lang.Exception
Unchecked exception is everything that inherits from java.lang.RuntimeException
Error is everything that inherits from java.lang.Error
Only Checked exception explicit need to catch it, for other all kind of exception you can use "throws" to the method signature.
Yes, but if you don't want to handle it in your method you can pass the exception to the caller of the method with the throws keyword. Example:
void execption() throws Exception {
throw new Exception();
}
void caller() {
try {
execption();
} catch (Exception e) {
e.printStackTrace();
}
}
Edit: I'm a bit rusty on my java, like josh said you can have unchecked exceptions that don't need a try/catch like NullPointerException, but you can add one if you think an unchecked exception may be thrown. Example:
Object obj = null;
obj.hashCode();// if you think a NPE will be thrown you can use a try/catch here
When a method that you call explicitly throws an exception then you have to use try....catch loop. But in case of the list you have given are all runtime exceptions. They get thrown when sometimes a program has inputs that were not expected or the program was put to some use that it was not intended for. These would not require a try....catch loop.

when throw new Error() is written in try block why catch block is not executed .it go in finally only .Latter code also not executed

Example bellow a program ,where in try block defectedCode() method is called ,So why only output shown only C with "Exception in thread "main" java.lang.Error".
public class ExceptionTest {
public static void defectedCode(){
throw new Error();
}
public static void main(String args[]){
try{
defectedCode();
System.out.println("A");
}catch(Exception e){
System.out.println("B");
}finally{
System.out.println("C");
}
System.out.print("D");
}
}
Exception in thread "main" java.lang.Error
C
at ExceptionTest.defectedCode(ExceptionTest.java:15)
at ExceptionTest.main(ExceptionTest.java:21)
Java Result: 1
The main reason for this is that you throw an Error but you catch an Exception.
If you look at the Throwable hierarchy the point is clear. You can't catch an Error with an Exception. Hence the catch block isn't entered and finally will be called.
Try this:
try{
defectedCode();
System.out.println("A");
}catch(Throwable e){
System.out.println("B");
}finally{
System.out.println("C");
}
You're not supposed to catch errors
An Error "indicates serious problems that a reasonable application should not try to catch."
while
An Exception "indicates conditions that a reasonable application might want to catch."
Talking about your code, you're throwing an error and catching an exception, it must be evident by now that they are 2 discrete entities
Error along with RuntimeException & their subclasses are unchecked exceptions. All other Exception classes are checked exceptions.
Checked exceptions are generally those from which a program can recover & it might be a good idea to recover from such exceptions programmatically. Examples include FileNotFoundException, ParseException, etc. A programmer is expected to check for these exceptions by using the try-catch block or throw it back to the caller
On the other hand we have unchecked exceptions. These are those exceptions that might not happen if everything is in order, but they do occur. Examples include ArrayIndexOutOfBoundException, ClassCastException, etc. Many applications will use try-catch or throws clause for RuntimeExceptions & their subclasses but from the language perspective it is not required to do so. Do note that recovery from a RuntimeException is generally possible but the guys who designed the class/exception deemed it unnecessary for the end programmer to check for such exceptions.
Errors are also unchecked exception & the programmer is not required to do anything with these. In fact it is a bad idea to use a try-catch clause for Errors. Most often, recovery from an Error is not possible & the program should be allowed to terminate. Examples include OutOfMemoryError, StackOverflowError, etc.
Do note that although Errors are unchecked exceptions, we shouldn't try to deal with them, but it is ok to deal with RuntimeExceptions(also unchecked exceptions) in code. Checked exceptions should be handled by the code.
Because Error is not Exception, so the catch block is not monitoring it
use throw new Exception()
An Error is not an Exception.
The base class for throwable objects is Throwable.
Errors and exceptions are two different types of throwables. However, errors are usually not supposed to be caught, which is why people use catch(Exception e) to catch basically all exceptions that they should catch.
Obviously, since Error is not a subclass of Exception, it's not affected by catch(Exception e), so it's not caught. finally is always executed, regardless of whether the throwable has been caught or not.
Though ethically you should not catch an error, you can still catch that as a Throwable Object.

How can I get a method to throw a custom exception I've created?

So my custom exception is PatternFormatException, and I've appended throws PatternFormatException, to the end of my method, but I'm wondering how I can actually get the method to physically throw it? Do I use if statements? i.e.
if //[doesn't_parse] throw PatternFormatException
This seems cumbersome for many different lines of code? Can I catch a more universal in built exception i.e. NumberFormatException, and then in the handling of this, throw my own exception?
You throw an exception using the throw keyword:
throw new PatternFormatException(...);
Generally you want to catch exceptions as early as they occur and handle them properly. If you want your parser (or whatever program you are writing) to generate meaningful errors, it's usually a good idea to wrap any caught exception and re-throw it, embedded in a more meaningful exception, giving the user a better idea of how things went wrong.
Something like this:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (Exception e) {
throw new PatternFormatException(..., e);
}
generally is fine, if you know exactly what exceptions might happen and if all of them are properly encapsulated by PatternFormatException. However, the key idea of Exceptions in Java is that you are always aware of all the possible Exceptions that can happen. That is why Java forces you to add all possibly thrown Exceptions (except for RuntimeException) to the method declaration.
A safer design would be:
try {
doSomething(); // throws SomeException
doSomethingElse(); // throws SomeOtherException
}
catch (SomeException e) {
throw new PatternFormatException(..., e);
}
catch (SomeOtherException e2) {
throw new PatternFormatException(..., e2);
}
catch (Exception e3) {
throw new UnexpectedPatternFormatException(..., e3);
}
Note that the first two catches call different constructors, and thus can handle different Exceptions differently. The last catch wraps an unexpected exception because your program encountered an exception (probably a RuntimeException) that you did not plan for. If users then complain about UnexpectedPatternFormatException, you can just go back to your code and fix the code so that the underlying Exception either does not get thrown anymore or gets wrapped in a more meaningful way. You can also just use a single UnexpectedMySomethingException class as the fall-back for all try/catch blocks that you have, to keep things a bit simpler.
One last word should be said about issues caused by Exceptions: Even though, Java uses Exceptions for all kinds of situations, even those that are largely not in the control of the Java programmer (e.g. when accessing files or even trying to parse strings as numbers), always be aware that throwing and catching Exceptions is actually quite expensive, which is why many people tend to avoid that. Only really use Exceptions, if performance is not of an issue (when the Exception is a rare event).
Also, Exceptions can threaten the integrity of your program's state if you throw an Exception and catch it too late, so that lines that should have been executed did not get executed (e.g. code for cleaning up resources or other code that is needed to keep the program state "correct"), and, as a result, the only safe thing to do is to shut down the program.
If I understand your question correctly you could just do this:
If(somethingBad){
throw new PatternFormatException();
}
As stated in a response below. If your going to check this exception over and over again you might want some Static Method/Class Method (use your programming brain). For example you could do something like:
void checkForException(String pattern, String check){
If(!check.equals(pattern)){
throw new PatternFormatException();
}
}
Now all you have to do is:
try{
checkForException("abc","123");
}catch(PatternFormatException pfe){
System.out.println(pfe); //Whatever you want to happen if the exception is thrown
}
Remember though, ONLY use exceptions for exceptional situations...
Have a read over this for more information on exceptions. I find that I next to never use exceptions.

Exceptions in java, rethrown [duplicate]

This question already has answers here:
Why Re-throw Exceptions?
(13 answers)
Closed 9 years ago.
In some legacy code I see this, that an overbroad exception is being caught, and then thrown again, Is this a good practice? Does throw e; rethrow the same exception, or create a new one ?
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
System.out.println(sb.toString());
throw e;
}
throw e is rethrowing the same exception. At least it preserves the original stacktrace. It's just writing a message to stdout recording some information about what happened, then letting the original exception proceed on its way.
It's not a great practice, it should be enough to log the exceptions in a central place, recording their stacktraces. If you need to add more information (as in the example, where it logs an id), it's better to nest the original exception in a new exception as the cause, then throw the new exception. I would guess this probably occurs in contexts where there is no centralized logging or where exceptions tend to get eaten somewhere.
This is usually a bad practice. catch(Exception e) (sometimes called Pokemon Exception Handling for when you gotta catch 'em all) catches every single exception. Such exception handling is rarely useful because:
It catches runtime exception too.
You lose information about the type of exception that was thrown.
You cannot react to or handle specific exceptions.
Your method signature now is public void whatever() throws Exception, which is rarely useful. Now everything further up the chain has no idea what kind of exception you have thrown; they will have to do instanceof checks which defeats the purpose of catching specific-exceptions entirely.
As far as your second exception is concerned, throw e; throws the same exception object. If you wanted to wrap the exception, you can create a new one, which means you would do something like throw new MyCustomException(e);. You would also need to change your method signature.
If there is nothing further up the chain, I guess this isn't as bad (still isn't great, though). It looks like a method that is trying to log all exceptions that are thrown. However, again, there are better ways of doing this.
throw e does throw the same exception. There might have been reasons for doing this, but there is also a reason not to. In your example code, a message is sent to System.out, but if a stack trace were printed later on System.err, it won't be syncronized, and in fact the two might end up interwoven in your console.
A better approach would be the following:
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
throw new Exception(sb.toString(), e); // The original exception is an argument
}
This will create a new Exception with the modified message, and append the original Exception to the stack trace to help with debugging.
My best guess would be it is trying to have two layers of protection. Making sure that an error message is displayed and also asking the client to handle the exception the way it wants to because the catch clause is not doing anything to recover from the exception.
I won't consider it good/bad practice. Depending on your requirements you can consider to go either way like there might be 100 of different clients using your API and each one of them has a different way of recovering from an exception. By displaying what went wrong it is adding a default action layer just below the layer where client decides on how it will handle the exception.
Now back to your question. I think throw e throws the same exception object. As exceptions are objects in java you need to create a new exception object before you can throw it which I can't see happening in your code.
It can be a good practice. I think I always use conversion to RuntimeExceptions during prototyping. After this if there is a need one can change this into better exception handling. For this my purpose there is an utility class in Guava called Throwables which makes exception propagation.
In your case however the exception should be converted into a runtime exception, because declaring a method throwing a general Exception is just the same as a method throwing RuntimeException for the calling party. In the first case it 'catches everything', in the latter it 'catches anything'. I have not yet experienced the difference between two of these in real-world applications. So I prefer RuntimeExceptions as they require less typing.
Catching Exception
Checked exceptions (IO exceptions, security errors, concurrency, etc)
Runtime exceptions (anything, unpredicted garbage, see below)
Everything - these are 99% of all errors (there are Errors left however)
Catching RuntimeException
null pointer exceptions, index out of bounds exceptions, access exceptions, + API which wraps propagates exceptions into RuntimeException - this is ALSO A LOT
My point is after when you're catching an Exception you can't really handle all these cases. So it makes no difference except for the less typing for the calling party if you wrap it into a RuntimeException.

How to know which exception is thrown

I'm doing a review for our codebase, and there are many statements like this:
try
{
doSomething()
} catch (Exception e)
{
}
but I would like a way to know which exception is thrown by doSomething() (there's no throw statement in the implementation of doSomething) so i can catch that exception instead of just catching Exception in general, even with findBugs it gives a warning REC_CATCH_EXCEPTION.
I should mention that logging the exception or printing it to console will not help me because it takes time in this case to reproduce the error that causes the exception here.
Thanks
If there's no throws statement in doSomething (e.g. doSomething() throws IOException), any exceptions that will occur will be an instance of RuntimeException. If you want to know the exact class of an exception thrown by doSomething, you can always try
try {
doSomething();
} catch (RuntimeException e){
System.out.println(e.getClass().getName());
}
Knowing which runtime exceptions can be thrown without actually running the program is difficult. Even if none of the code that doSomething() calls has an explicit throw, core java operations can always throw NullPointerException, ArrayIndexOutOfBoundsException, etc with the wrong input. Here are some ideas:
Dig through manually. At least you will know some of the exceptions.
Use reflection to find any throw statements accessible from doSomething.
Run your test cases and log the exceptions thrown like above. Good tests will reveal the important errors that callers of doSomething should be ready for.
Go to the people who put the catch there in the first place
In any case it's usually a good idea to catch exceptions that are as specific as possible, since you don't know exactly what went wrong when you try to deal with all cases in one clause.
You can 1) dig through all the code in doSomething() and everything it calls to see the exception handling and what RuntimeExceptions can be thrown, or 2) take of the catch (Exception e) and wait for it to fail. This is the problem that checked exceptions attempted to overcome by making a strongly-typed declaration in method signatures about what exceptions must be handled as a result of calling the method.
If there is no throws clause, then the method does not throw any checked execption. The javadoc of that method might give information about any unchecked exceptions the method can throw, but it does not have to.
Why do you want to catch any exceptions in the first place?
Do you want to catch just compile-time exceptions or run-time exceptions as well? If you only want to catch the compile-time ones, just remove your current catch block - you'll immediately get error messages stating that certain exceptions aren't being caught. After you add one exception, you'll see error messages for others - you'll be able to finish catching all possible exceptions thrown by your code block.

Categories

Resources