Why is the code
void methodThrowsException() /*throws Exception*/{
try {
// throw new Exception();
} catch (Exception e) {
throw e;
}
}
well compiled?
AFAIK compiler doesn't analyse code for can it throw an exception or not.
Here obvious throw e; will never run (due to commented // throw new Exception();), but why does compiler know this?
The javac compiler really doesn't do much of optimisation. But simple dead code detections and optimisations are yet possible.
In your example: the compiler can easily detect that the try block is empty. Empty try blocks can't throw, so all catch block code is essentially dead.
So the compiler could go in and simple drop the whole try/catch altogether here. Then there is nothing left that could throw an exception.
Which, when we use javap is exactly what we find in bytecode:
void methodThrowsException();
Code:
0: return
And yes, the other answer is fully correct: this only works this way because you are using Exception, a more specific (checked) subclass will lead to a compiler error.
The compiler will detect specific checked exception that are not thrown e.g.
void methodThrowsException() {
try {
} catch (URISyntaxException e) {
throw e;
}
}
will result in compiler error:
exception java.net.URISyntaxException is never thrown in body of corresponding try statement
but it won't check runtime exceptions, or the exception hierarchy root types like Exception, Error, Throwable. This is explained in JLS 11.2.3. Exception Checking.
fb-contrib complains about
Method throws alternative exception from catch block without history
in one of my try/catch blocks.
How can this be fixed ? Is there a detailed explanation about how to fix this ?
Original exception is caught, your code throws another exception without including the original in the java.lang.Throwable cause
Found something here:
This method catches an exception, and throws a different exception, without incorporating the
original exception. Doing so hides the original source of the exception making debugging and fixing
these problems difficult. It is better to use the constructor of this new exception that takes an
original exception so that this detail can be passed along to the user.
Nice catch by FindBugs contrib !
So pass the cause, log it, ... do something with what you caught.
Hope this helps someone.
Example:
try {
...
} catch (final SomeException theOriginalCause) {
// throw new SomeOtherException(); // Bad !
throw new SomeOtherException(theOriginalCause); // Good.
}
This question already has answers here:
When to catch the Exception vs When to throw the Exceptions?
(8 answers)
Closed 3 years ago.
So I have two general questions about java in general. The first is when would one use a try/catch in the body of the method versus using throws exception in declaring the method? Here is a little demonstration of what I mean. This:
public void whileChatting() throws IOException{}
versus
public void closeConnection() {
try {
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
And then my second question is when does one know what type of exception to either catch or throw? By that I mean exceptions such as IOException or EOFException and so on...
If there's a good link someone could send me teaching all this (being that it's probably more complicated than I think) I would be just as grateful as if you answered it.
Thanks.
Throwing Exceptions
In your first example,
public void whileChatting() throws IOException{}
means that it will just throw the exception to whatever is calling the function. It can then be caught while calling that method with a try-catch block. such as
try{
whileChatting();
}
catch(IOException e){
e.printStackTrace();
}
Throwing a method basically propagates it up the chain, and so any method that calls this method will need to also include throws IOException, or the exception will need to be dealt with in the higher level method (by means of a try-catch block usually).
Catching Exceptions
Catching an exception is a way to gracefully deal with exceptions. The common thing to do is e.printStackTrace(); which prints details of the error to the console, however it's not always necessary. Sometimes you may want to do a System.exit(0) or even a System.out.println("Error in method whileCalling()")
With a catch block you can catch any type of exception! you can also do a try-catch-finally block which will run the code in the try block, catch any exceptions, and whether or not any exceptions are caught it will enter the finally block and run that code.
To know what Exception you might need to catch, you can look at the Javadocs for the class that may throw the exception. There you will find a list of every possible thing that the class can throw. You can also just catch Exception which will catch any Exception imaginable! (Well, granted it extends Exception)
And finally you can link catch blocks together like so.
try{
whileCalling();
}
catch(IOException e){
//handle this situation
}
catch(FileNotFoundException e){
//handle this situation
}
catch(Exception e){
//handle this situation
}
This will work like and else-if block and not catch duplicates.
So to answer your questions basically:
1: To throw an Exception means to have somebody else deal with it, whether this be another class, another method, or just to hoping it doesn't happen or else your program will crash(pretty bad practice).
2: To use a try catch block is to actually deal with the Exception however you see fit! printing out the stacktrace for debugging or giving the user a new prompt to re-input something maybe. (For instance a prompt that the user needs to enter a file location and then it throws a FileNotFoundException)
Hope that helps!
Two good rules of thumb:
You should only catch exceptions that you can actually handle
Throw Early/Catch Late
There's no hard and fast answer.
In general, you'll probably use "throws" much more often than you'll have a custom "try/catch". Simply because you'll have relatively few "decision" modules that "know how to recover", but you'll have correspondingly "many" modules that could throw exceptions.
You use try/catch when you want to treat its reason, otherwise you should propagate it so it can be treated at the right time.
A good start would be javadoc and tutorialspoint for exceptions
Basically is something like this:
throws - the function that throws and exception tells it's parent function that somenthing it's wrong. For instance you have a createFunction() throws SQLException where you are trying to insert 100 item in a database but the creation of number 98 fails. The createFunction() is used in your main() who receives this SQLException;
try/catch - the main() knows that createFunction() is suppose to throw an SQLException if something goes wrong so when it implements it puts it in a try/catch block, this way if an SQLException is actually thrown you can execute a fall-back plan in the catch block such as a database rollback.
Actual code of what I just said:
createFunction(Connection connection) throws SQLException {
//insert items in the database
}
main(){
try{
createFunction(connection);
}
catch (SQLException e){
connection.rollback();
}
}
I am working in Linux/Ubuntu. I want to run a process in through my java code, which looks like below
ProcessBuilder pb = new ProcessBuilder("/usr/lib/flume-ng/bin/flume-ng",
"agent",
"-f",
"/home/c4/Flume/New/ClientAgent.config",
"-n",
"clientAgent");
pb.start();
But i get unreported exception java.io.IOException; must be caught or declared to be thrown pb.start(); as error output. Please tell me how i can run my process. Thanks.
It's telling you the start() method could throw an Exception, and you have to deal with it. You can either:
catch it and log it or otherwise handle it, or
declare your method as possibly throwing this exception, and let a method higher up the stack handle it (using these two options)
The Exception object is checked, which means the compiler is concerned with it, and you need to be too (however much of a pain that is). Other exceptions are unchecked, and this means you don't have to worry. The compiler won't worry either (e.g. OutOfMemoryError - be aware that I'm mixing some exception terminology here, since it's a little convoluted).
Since, IOException is a checked exception you need to either catch it
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
or throw it with the enclosing method declared to do so.
public void yourMethod() throws IOException {
I was trying to understand why to use exceptions.
Suppose if I have an program,
(without using try/catch)
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
System.out.println(str.length());
}
I got exception
Exception in thread "main" java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:22)
Now using try/catch,
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
npe.printStackTrace();
}
}
}
I got Exception,
java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:9)
Now my question is,
In both the cases I have got the same message printed. So what is the use of using try/catch? and
What can we do after catching exception, in this case I have printed the stack trace. Is catch used only for printing the trace or for finding exception details using getMessage() or getClass()?
The difference is pretty big, actually.
Take the first one and add a line after the print:
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
System.out.println(str.length());
System.out.println("Does this execute?");
}
}
You'll see that Does this execute? isn't printed because the exception interrupts the flow of the code and stops it when it isn't caught.
On the other hand:
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("Does this execute?");
}
}
Will print both the stack trace and Does this execute?. That's because catching the exception is like saying, "We'll handle this here and continue executing."
One other remark, the catch block is where error recovery should happen, so if an error occurs but we can recover from it, we put the recovery code there.
Edit:
Here's an example of some error recovery. Let's say we have a non-existent file at C:\nonexistentfile.txt. We want to try and open it, and if we can't find it, show the user a message saying it's missing. This could be done by catching the FileNotFoundException produced here:
// Here, we declare "throws IOException" to say someone else needs to handle it
// In this particular case, IOException will only be thrown if an error occurs while reading the file
public static void printFileToConsole() throws IOException {
File nonExistent = new File("C:/nonexistentfile.txt");
Scanner scanner = null;
try {
Scanner scanner = new Scanner(nonExistent);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException ex) {
// The file wasn't found, show the user a message
// Note use of "err" instead of "out", this is the error output
System.err.println("File not found: " + nonExistent);
// Here, we could recover by creating the file, for example
} finally {
if (scanner != null) {
scanner.close();
}
}
}
So there's a few things to note here:
We catch the FileNotFoundException and use a custom error message instead of printing the stack trace. Our error message is cleaner and more user-friendly than printing a stack trace. In GUI applications, the console may not even be visible to the user, so this may be code to show an error dialog to the user instead. Just because the file didn't exist doesn't mean we have to stop executing our code.
We declare throws IOException in the method signature instead of catching it alongside the FileNotFoundException. In this particular case, the IOException will be thrown here if we fail to read the file even though it exists. For this method, we're saying that handling errors we encounter while reading the file isn't our responsibility. This is an example of how you can declare an irrecoverable error (by irrecoverable, I mean irrecoverable here, it may be recoverable somewhere further up, such as in the method that called printFileToConsole).
I accidentally introduced the finally block here, so I'll explain what it does. It guarantees that if the Scanner was opened and an error occurs while we're reading the file, the Scanner will be closed. This is important for many reasons, most notably that if you don't close it, Java will still have the lock on the file, and so you can't open the file again without exiting the application.
There are two cases when you should throw an exception:
When you detect an error caused by incorrect use of your class (i.e. a programming error) throw an instance of unchecked exception, i.e. a subclass of RuntimeException
When you detect an error that is caused by something other than a programming error (invalid data, missing network connectivity, and so on) throw an instance of Exception that does not subclass RuntimeException
You should catch exceptions of the second kind, and not of the first kind. Moreover, you should catch exceptions if your program has a course of action to correct the exceptional situation; for example, if you detect a loss of connectivity, your program could offer the user to re-connect to the network and retry the operation. In situations when your code cannot adequately deal with the exception, let it propagate to a layer that could deal with it.
try/catch will prevent your application from crashing or to be precise- the execution will not stop if an unintentional condition is met. You can wrap your "risky" code in try block and in catch block you can handle that exception. By handling, it means that do something about that condition and move on with execution.
Without try/catch the execution stopped at the error-making-line and any code after that will not be executed.
In your case, you could have printed "This was not what I expected, whatever, lets move on!"
Let's say you are connected to database but while reading the records, it throws some exception. Now in this particular case, you can close the connection in Finally block. You just avoided memory leak here.
What I meant to say is , you can perform your task even if exception is thrown by catching and handling it.
In the example you've given, you're right, there is no benefit.
You should only catch an exception if either
You can do something about it (report, add information, fix the situation), or
You have to, because a checked exception forces you to
Usual "handling" of an exception is logging the situation to a log file of your choosing, adding any relevant context-sesitive information, and letting the flow go on. Adding contextual information benefits greatly in resolving the issue. So, in your example, you could have done
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
System.err.println(
"Tried looking up str.length from internal str variable,"
+" but we got an exception with message: "
+ npe.getMessage());
npe.printStackTrace(System.err);
}
}
when looking a message like that, someone will know based on the message what went wrong and maybe even what might be done to fix it.
If you are using Exception, don't
catch(NullPointerException npe) {
npe.printStackTrace();
}
simply
catch(NullPointerException npe) {
//error handling code
}
You are menat to remove error printing. And anyways catch general exception not just specific ones.
If you look at the two exceptions, they are actually different. The first one is referring to line 22, while the second one is referring to line 9. It sounds like adding the try/catch caught the first exception, but another line of code also threw an exception.
Consequently, the exception is being thrown because you never created a new String, or set a value to the string, unless it was done in a part of the code that is not shown.
Adding a try/catch block can be very helpful with objects that you have little to no control over, so if these objects are other than expected (such as null), you can handle the issue properly.
A string is normally something that you would instantiate first, so you shouldn't normally have to worry about using a try/catch.
Hope this helps.
To answer your original question Che, "when to use an exception?"
In Java - I'm sure you've already found out... There are certain methods in Java that REQUIRE the try / catch. These methods "throw" exceptions, and are meant to. There is no way around it.
For example,
FileUtils.readFileToString(new File("myfile.txt"));
won't let you compile until you add the try/catch.
On the other hand, exceptions are very useful because of what you can get from them.
Take Java Reflection for example...
try { Class.forName("MyClass").getConstructor().newInstance(); }
catch ( ClassNotFoundException x ) { // oh it doesnt exist.. do something else with it.
So to answer your question fully -
Use Try/Catch sparingly, as it's typically "frowned on" to EXPECT errors in your application.. on the contrary, use them when your methods require them.