public class StackTest {
public static void main(String[] args) {
show();
System.out.print("welcome back to maain");
display();
}
static void show(){
try{
show(); //recursion
}catch(StackOverflowError e){
System.out.print("error cought");
}
}
static void display(){
System.out.print("after stack overflow error");
}
}
In this program an StackOverflowError occurs but gets handled and the program does not terminated abnormally. why?
You can see this at http://ideone.com/vwSav
You can handle Errors because they are Throwable just like Exceptions.
Errors are designed to indicate problems outside your program's control, like OutOfMemoryError and StackOverflowError, but you can define your own errors, too.
Perhaps you are thinking that, or heard that, OutOFMemoryError can be caught but there's no guarantee you'll have enough space to execute the handler, so errors must in general not be something you can catch. In your case, though, you got away with it. No language rules were violated in the catching and handling of this error.
The real question is, should you catch them? Normally when an error, as opposed to an exception, is thrown, your application is very likely in an inconsistent state, making recovery a crapshoot at best. So be really, really careful. Better to forget it and let the app die though, since whatever is running after the handler is not guaranteed to be something you'd want to run.
Why would you expect it to terminate when you catch the exception (or rather the Error in this case)? What else would that catch block do?
You can catch and handle pretty much all error conditions, though usually you should only catch Exceptions.
You can catch any Throwable and it is up to the developer to handle it correctly. You can even handle ThreadDeath (triggered by a Thread.stop()) or another sub-class of Throwable (which is neither an Error or an Exception)
public class MyThrowable extends Throwable { } // checked "exception"
try {
throw new MyThrowable();
} catch (Throwable t) {
t.printStackTrace();
Thread.currentThread().stop(t); // rethrow blindly.
}
It will only be terminated abnormally if your exception is propagated all the way up to your main method and you don't handle it there. Usually happens for unchecked run time exceptions. If you want to terminate your program and shut down the VM you can call System.exit(int errorCode) in the catch block, there will be programmers which always complain here if that's done but that's a way to do it.
usually you don't catch Error, except for LinkageErrors, no class def found errors, unsatisfied link errors, incompatible class change errors..
also an outofmemory error (sometimes the stackoverflow exception) doesnot give control the catch block as there is no memory.
Related
Here is my code:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
outputStream.write(signature.getR());
outputStream.write(signature.getS());
outputStream.write(signature.getV());
} catch (java.io.IOException exception) {
// WHAT GOES HERE?
}
The Java documentation tells me that this ByteArrayOutputStream might throw an IOException. And so the compiler requires me to put this in a try/catch block.
Based on the fact that I am concatenating only about 100 bytes, and I am not closing the stream in the meantime, I do not expect any errors.
Or more clearly, I don't want to handle or pass of any errors.
In Swift I would do this with an assertion (try!).
In Java how do I make it so that an exception here results in the program terminating and does not require me to bubble up exceptions the whole way?
Invalid/Inconsistent/Unexpected scenarios
Checked Exceptions - expected and caller should be aware (runtime course correction)
Unchecked Exceptions - unexpected and caller need not take course correction (back to coding, fix and redeploy)
Checked Exceptions
Possible invalid state of operation where the immediate caller can take a course correction
Or else propagate such exception up in call hierarchy by adding to throws
Or turn into a Unchecked exception due to this being an unacceptable state due to bug and decide on caller's decision
Silently consume(catch) and proceed as though nothing happened
Why IO operations are generally Checked?
The IO(network) could be unavailable temporarily so that caller can retry
IO(File) permission might be incorrect and hence caller can try an alternate action (different path or change permissions if allowed)
Insufficient resource(space) and the caller can free up some resource and retry
Invalid path and hence write to different path (or create the path)
Unchecked Exceptions
Invalid states which should not happen at runtime (say NPE)
Unexpected states like Stack overflow Error, Out of memory error (though caller can course correct by taking an alternate action like unreferencing to GC large objects or call iterative logic instead of recursive logic). These actions should be decided by developer at compile time and should not be generally handled at runtime.
Java states
Throwable - any invalid state - Unchecked
Exception - primarily predicted invalid states (unpredicted too with RuntimeException) - Checked for everyone except RuntimeException hierarchy
RuntimeException - a special type of Exception for unpredicted or should not happen or no alternative - Unchecked
Error - abnormal and could not handle - Unchecked
Assuming the call is for write(int), it is safe to ignore for this specific use case
ByteArrayOutputStream.write(int) will not throw checked exception
There is no checked exception defined for .write(int) Doc
But the parent class OutputStream has checked exception.
So, catch block can be left empty or its not even required unless you are using the OutStream as the reference to hold the ByteArrayOutputStream object
The following code works perfectly fine in JDK 11 compiler and runtime
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
b.write(65);
System.out.println(b.toString());
}
It can throw NPE for null input (technically this is unboxing error)
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
Integer input = null;
b.write(input);
System.out.println(b.toString());
}
If its write(byte[]), then OutputStream.write throws checked exception and hence it has to be caught.
But it can throw other runtime exceptions too.
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
try {
b.write((byte[])null); // NPE
} catch (IOException e) {
System.out.println(e);
} catch (RuntimeException e) {
System.out.println(e);
}
}
catch (java.io.IOException exception) {
throw new UncheckedIOException(exception);
}
One of the reasons for introducing UncheckedIOException in Java 8 was to hide the abuse of IOException in Java, and shut the compiler up. Very useful for lambdas that can't throw checked exceptions.
I know questions like this are everywhere, but I read a lot of things about this, and I still can't understand what the "throws" command do. I will be more specific now:
So, one of the examples I saw was this one, with the following code:
public class CatchThrow {
private static void throwsMethod() throws NumberFormatException {
String intNumber = "5A";
Integer.parseInt(intNumber);
}
private static void catchMethod() {
try {
throwsMethod();
} catch (NumberFormatException e) {
System.out.println("Convertion Error");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
catchMethod();
}
}
Now, if I remove the "throws NumberFormatException" from the "throwsMethod" method, the program will run the same, and will give the same results. Actually, every example with the throws command that I saw did the same, so I can't really understand why use it.
I'm using the Eclipse IDE, version 4.7.2.
Normally your function exits at the end of the function or the return statement.
However, a function can also exit when it reaches a throw statement. If the exception subclasses Exception, the caller of the function must surround the function call with a try { } catch { } block. If the exception subclasses RuntimeException you may optionally surround the function call in a try catch block.
If you look at the JavaDoc for NumberFormatException: https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html will see it subclasses RuntimeException. This means your try-catch block is optional. The difference between the two program is this: With the try-catch block you will get Convertion Error printed to the console, without it, you will see the full stack trace. This is often called "swallowing the exception".
So basically, if an exception occurs and you don't want to handle that exception there, in that case you use the 'throw' keyword to simply just throw the exception if occurs.
Example: Here, in throwsMethod(), you are not taking care of the Exception Handling i.e. not using the try(), catch() blocks, you are just throwing it if there occurs any Exception. And you will land in catch() block if exception occurs in your throwsMethod().
To get better idea, you should read checked & Unckecked exceptions in Java. For Checked exceptions (happen at compile-time), we use 'throw' keyword and for Unchecked (Run-time), we use try() catch().
Example: NumberFormatException is an Unchecked exception, IOException is a Checked exception.
Read this for reference: https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/
I'm using a third-party java library and this library class has a method called doSomething:
Library.doSomething();
In the course of the doSomething method, it sometimes throws a java.net.SocketException, but the doSomething method does not declare the SocketException as a checked exception. So when I try to write:
try {
Library.doSomething();
} catch (java.net.SocketException error) {
error.printStackTrace(); // and do other recovery stuff
}
I get the following compiler error:
Unreachable catch block for SocketException. This exception is never thrown from the try statement body
However, I know that at runtime the doSomething method frequently throws the SocketException. I know that I can catch a generic java Exception and then check to see if it is a SocketException, but is there any more elegant way to catch the SocketExceptions thrown by this third party closed source library?
Thanks!
Edit - It turned out the SocketException is wrapped in a WebServiceException and I just missed the wrapped exception in a crowded error log. So there really isn't any question to answer. Sorry for the confusion.
Mena's answer is very good, but I just want to state that there are ways (4 of them if I recall correctly, I mention them in the comments) to throw check exceptions that are not declared.
As a solution I suggest catching something general like Exception and check the type of the caught exception (using instanceof is recommended).
You should write
catch (Exception e) {...}
Because compiler returns error if the catch block will never (or hardly ever) execute. In the catch block, you can compare the Exception using "instanceof" statement to get an information about specific exception.
I know that I can catch a generic java Exception and then check to see if it is a SocketException, but is there any more elegant way to catch the SocketExceptions thrown by this third party closed source library?
There is no alternative that will actually deal with the exception; i.e. allow you to actually handle it in the normal fashion.
Basically, the 3rd-party library has broken Java's checked exception rules. It is faulty and should be fixed.
FWIW, the code to work around the 3rd-party library bug is a "delicate":
try {
callNastyMethod();
} catch (Exception ex) {
if (ex instanceof SocketException) {
// handle the exception we are expecting
} else if (ex instanceof RuntimeException) {
// unexpected runtime exceptions should be rethrown
throw (RuntimeException) ex;
} else {
// deal with any other checked exceptions; for example.
throw AssertionError("Unexpected checked exception", ex);
}
}
I'm starting to teach myself more about Java error handling, and this is my first program where I'm trying to see specific errors instead of using catch (Exception e) as a generic catch-all catch.
I'm deleting a file and returning a message that the file was deleted successfully or that the deletion was a failure. In cases where the deletion fails, I want to deliver an error message if the file is not found.
Here's where I am so far:
public static void deleteOldConcatFiles(File concatFile) {
try
{
if(concatFile.delete()) {
System.out.println(concatFile.getName() + " is deleted!");
} else {
System.out.println("Delete operation failed.");
}
}
//
catch(FileNotFoundException f) {
System.out.println("Exception: "+ f.getMessage().getClass().getName());
}
}
When I run that, I'm getting a warning: This this is an unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body.
However, when I run with THIS catch block,
catch(Exception f) {
System.out.println("Exception: "+e.getMessage().getClass().getName());
}
I get no error or warning message.
Why is this happening, and what can I do to fix it?
File.delete() does not throw FileNotFoundException, even if the file does not exist.
FileNotFoundException is a checked exception (i.e., not a RuntimeException), so any code that throws it must declare it. Because File.delete() does not declare that it throws FileNotFoundException, the compiler guarantees that it won't, and can promise that your catch block will never be invoked.
The second, catch-all block does not generate a warning because it also catches RuntimeExceptions (RuntimeException extends Exception), which the compiler does not check for you. Thus, it might be invoked, the compiler isn't sure, so it doesn't warn you.
Java supports two kinds of exceptions: checked exceptions (statically checked) and unchecked exceptions (RuntimeException and its subtypes).
The Java compiler can tell at compile time whether a checked exception (such as FileNotFoundException) can be thrown or can definitely not be thrown. It can't tell that for unchecked exceptions (such as IndexOutOfBoundsException). So it will warn about attempts to catch checked exceptions that cannot arise.
If you catch Exception, it will never complain, because RuntimeException is a subtype of Exception, so your attempt will also try to catch exceptions such as IndexOutOfBoundsException.
As others have noted, FileNotFoundException is never thrown by delete. Furthermore it is a checked exception. So the Java compiler will complain.
Because the type of error thrown doesn't match the one you're catching. Try this...
catch(Exception e) {
System.out.println("Exception: "+ e.getClass());
}
That will show you the type of error you should be catching. Obviously this isn't good practice but it's a good exercise for seeing what's happening. Other answers on this page concerning checked and unchecked exceptions are pretty concise.
If you look at the manual here delete() only throws a SecurityException.
Also, it returns a boolean value which indicates whether or not the file was deleted. This should be all the information needed to indicate to the user if everything worked out.
Isnt the message clear? As you dont construct a File object, a FileNotFoundException can never be thrown in this try block. Therefor the compilers informs you that the catch block in unneccessary.
Look for IOException. or deleteifExist method if you are not interested in the exception, if you want to retrn something, then file.exists() will help you fgure if the file is there or not.
I had a strange problem today... I'm going to make a simplified example since it "worth a thousands words" :D
public class Application() {
public static void main(String[] args) {
try {
A a = new A(); // this may throw exceptions
// (which will cause an ExceptionInInitializerError)
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, "Oooops!");
System.exit(1);
}
}
}
Since it's a stand-alone application with a Swing GUI, my goal is to give a message to the user in case of any problems (in this case at startup)... the code above works in Eclipse IDE but when I export the project as executable jar by double-clicking on it, well, it just won't open.
So I try to execute it in cmd with java -jar application.jar and it prints in the shell that there was an ExceptionInInitializerError.
Why the error was not caught?
It doesn't work even if I specify catch (ExceptionInInitializerError e).
EDIT:
After more indepth debugging, I found out that this problem only happens when two particular exceptions occur and the latter occurs in the catch block of the former.
I corrected the bug by changing the order of some checks that I do on startup.
The problem btw should never happen since it was originated by a volountary mistake of the JDBC driver class name to load in a static block.
Well, at least it made me clearly understand why constructors and static initialization blocks should not throw exceptions: it makes debugging almost impossible in the case in which the class that throws the exception is used by many classes, since it may become very hard to find out when the class is loaded.
I can think of three possible explanations for an ExceptionInInitializerError not being caught in your example:
It could be being thrown by JOptionPane.showMessageDialog(null, "Oooops!");
It could be thrown before main is called.
It could be thrown on a different stack.
In fact, I think that the 2nd one is the most likely, as ExceptionInInitializerError is thrown when some unchecked exception is thrown (and not caught) during the initialization of a class. That could well be happening before you enter the try block.