interface AutoClosable has following method declaration:
void close() throws Exception
Thus we see that method close can throws Exception.
When I write code try-with resources it is looks like this:
private static void printFileJava7() throws IOException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
}
At this code is absent Exception handling.
I don't understand what happens if close method throws exception.
Java catches and suppresses exceptions thrown by the close method in a try-with-resources block.
You can read more about this here, see in particular the paragraph after the second code sample. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
You are right that close() method defined in AutoClosable throws exception. However other interface named Closable that extends AutoClosable redefines this method as following:
void close() throws IOException
All IO related classes implement Closable, so their close() method throws IOException. But your method throws it too, so in your code no-one catches this exception. As always it will be caught by upper layer of your application or by JVM itself if no-one catches it before.
From the jls about Compile-Time Checking of Exceptions
When interfaces are involved, more than one method declaration may be overridden by a single overriding declaration. In this case, the overriding declaration must have a throws clause that is compatible with all the overridden declarations (ยง9.4.1).
So when you have something like
static class AC implements AutoCloseable {
#Override
public void close() throws Exception {
throw new Exception("btooom!");
}
public void ac() {
System.out.println("no");
}
}
public static void main(String[] args) throws Exception {
try(AC ac = new AC()) {
ac.ac();
}
}
then you are forded to either add a catch clause to the surrounding try block or add a throws declaration.
In the case of FileInputStream and to apply what the jsl states, the AutoCloseable's close method is overriden from Closeable's, hence you only have to catch an IOException or add it to throws clause.
Further the javadocs of AutoCloseable#close states
While this interface method is declared to throw Exception, implementers are strongly encouraged to declare concrete implementations of the close method to throw more specific exceptions, or to throw no exception at all if the close operation cannot fail.
The key to this particular scenario is the "supressed exception".
"Whenever an exception is thrown within the body, and then followed
by an exception thrown by the try-with-resources statement, only the
exception thrown in the body of the try is eligible to be caught by
the exception handling code. All other exceptions are considered supressed exceptions"
A concept that is new with Java 7.SO you will get the same output as when only the printfileJava7 class throws an exception, since the CloseException thrown by the close() method would be suppressed.
Please refer to When two exceptions are thrown by the try-with-resources construct link.Which have taken exact scenario what You have asked
You need to have a catch block followed by try in the method printFileJava7(). If you don't want to catch it here, you need handle it in the method which calls the method printFileJava7(). We have to catch in one of the layers otherwise it will be propagated back to the calling client.
Related
This question already has answers here:
Difference between throw and throws in Java? [duplicate]
(3 answers)
Closed 3 years ago.
I saw a video that explains throws and throw as follows:
Throws - is used to delegate/pass on the exception to the caller method.
class test{
void child() throws filenotfoundException{
//////## this method passes the exception to its caller which is main method
File f = new File("abc")
}
public static void main(String[] args) throws filenotfoundException{
//////##this main method passes the exception to its caller which is JVM
}
}
So in the above example, if file 'abc' doesn't exist, and the exception is not handled using try catch in the child method, the child method will pass on the exception to main method.
As the main method doesn't handle the exceptions using try catch, it also throws or passes the exception to its caller method which is JVM.
Is it correct?
Throw - JVM only understands the logic to pick up predefined exceptions. And hence all the user defined exceptions should manually be created using new Exception and then passed on to JVM using throw keyword.
is it right as well?
The explanation is flawed. First, child() as written isn't going to throw a thing. File not found is not an exception so far and wouldn't be unless you tried to open the file for input.
From your code, though, child() could possibly throw the exception, as could main(). Child doesn't, but it's defined that it might.
Throw is how you actually, well, throw the exception. Like this:
void child() throws FileNotFoundException {
File f("garbage");
if (!f.exists()) {
throw new FileNotFoundException("the world is clean as garbage does not exist");
}
}
Your main() doesn't have a try/catch block, but it could:
void main() {
try {
child();
}
catch (FileNotFoundException e) {
// Oh no!
}
}
throws is used in the method signature to tell everyone that "yes, this method throws an Exception of X type, please be wary" while throw is used to actually launch this Exception and abort the execution of the function.
Yes, depending on the exception, and if you catch it or not, it might bubble all the way up to the JVM. Some Exceptions do not cause the execution to abort however. These are known as RuntimeExceptions. The programmer can decide to handle them, or not, using a try/catch block. RuntimeExceptions do not need to be declared in the function signature.
What is the point of catching and then also throwing an Exception like below? Is it bad practice to do both?
try{
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
Usually, such code is used to re-wrap exceptions, that means transforming the type of the exception. Typically, you do this when you are limited in what exceptions are allowed out of your method, but internally other types of exceptions can happen. For example:
class MyServiceImplementaiton implements MyService {
void myService() throws MyServiceException { // cannot change the throws clause here
try {
.... // Do something
} catch(IOException e) {
// re-wrap the received IOException as MyServiceException
throw new MyServiceException(e);
}
}
}
This idiom enables to keep propagating exceptions to the caller, while conforming to the throws clause in the interface and hide the details of the internals (the fact that IOExceptions can happen).
In practice, this is always better than just calling e.printStackTrace() which will actually "swallow" the error condition and let the rest of the program run as if nothing had happened. In this respect, behaviour of Eclipse is quite bad as it tends to auto-write such bad-practice constructs if the developer is not careful.
This is called rethrowing an exception, and it is a common pattern.
It allows you to change the class of the exception (such as in this case), or to add more information (also the case here, as long as that error string is meaningful).
It is often a good idea to attach the original exception:
throw new RuntimeException("cause of the problem", e);
Rethrowing as an unchecked exception (a RuntimeException) is sometimes necessary when you still want to throw an exception, but the API of your method does not allow a checked exception.
In your example, an Exception is caught and a RuntimeException is thrown, which effectively replaces a (potentially) checked exception with an unchecked exception that doesn't have to be handled by the caller, nor declared by the throwing method in a throws clause.
Some examples :
This code passes compilation :
public void SomeMethod ()
{
try {
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
}
This code doesn't pass compilation (assuming "something" may throw a checked exception) :
public void SomeMethod ()
{
//something
}
An alternative to catching the Exception and throwing an unchecked exception (i.e. RuntimeException) is to add a throws clause :
public void SomeMethod () throws Exception
{
//something
}
This is one use case of catching one type of exception and throwing another. Another use case is to catch one type of exception and throw another type of checked exception (that your method declares in its throws clause). It is sometimes done in order to group multiple exceptions that may be thrown inside a method, and only throw one type of exception to the caller of the method (which makes it easier for them to write the exception handling code, and makes sense if all those exceptions should be handled in the same manner).
I read that the catch block in try-with-resources is optional.
I've tried creating a Connection object in a try-with-resources block, with no subsequent catch block, only to get compiler error from eclipse:
"Unhandled exception type SQLException thrown by automatic close() invocation."
Since every resource that can be used in try-with-resources implements AutoCloseable, and so potentially throws an exception upon invocation of the close() method, I don't understand how the catch clause is optional, given that it's not allowing me to skip catching the exception from close().
Is there some special requirement that the specific implementation of AutoCloseable not directly declare any exception thrown in its close() method? (e.g. override AutoCloseable's close() throws Exception with a close() which does not throw any Exception)?
..or is this possibly just an eclipse issue?
Edit: Here's the simplest code fragment that still triggers the problem:
try (Connection con = dataSource.getConnection()) {
/*...*/
}
Thoughts on whether or not this is related to the use of a JNDI DataSource?
Thanks in advance.
It is optional if close() is not able to throw a checked exception. However, if close() can, then a checked exception would need to handled in a normal fashion, either with a catch block, or by throwing from the method that try-with-resources block is in.
More details are in JLS 14.2.3
14.20.3.2. Extended try-with-resources
A try-with-resources statement with at least one catch clause and/or a finally clause is called an extended try-with-resources statement.
The meaning of an extended try-with-resources statement:
try ResourceSpecification
Block
[Catches]
[Finally]
is given by the following translation to a basic try-with-resources statement nested inside a try-catch or try-finally or try-catch-finally statement:
try {
try ResourceSpecification
Block
}
[Catches]
[Finally]
The effect of the translation is to put the resource specification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.
Furthermore, all resources will have been closed (or attempted to be closed) by the time the finally block is executed, in keeping with the intent of the finally keyword.
Thoughts on whether or not this is related to the use of a JNDI DataSource?
Yes, it is.
In the example try-with-resourses block you've provided, it is necessary to catch the exception and handle, or throw from the method the block is in, because SQLException is a checked exception.
You could just be throwing the exception up (or catching it in another try-catch block):
private static void test() throws IOException {
try(InputStream is = new FileInputStream("test.txt")) {
while(is.read() > -1) {
}
} finally {
// Will get executed, even if exception occurs
System.out.println("Finished");
}
}
You can create an AutoClosable that does not require an explicit catch-block by declaring your AutoClosable's close() method without any Exception or with a RuntimeException. Without any Exception it is clear that no catch-block is required. Further, the compiler does not statically check for a RuntimeException to be catched (in contrast to checked Exceptions).
Example:
public class AutoClosableDemo
{
public static void main( final String[] args )
{
try (MyAutoCloseable1 mac1 = new MyAutoCloseable1())
{
System.out.println( "try-with-resource MyAutoCloseable1" );
}
try (MyAutoCloseable2 mac2 = new MyAutoCloseable2())
{
System.out.println( "try-with-resource MyAutoCloseable2" );
}
// The following is not allowed, because
// "Unhandled exception type Exception thrown by automatic close() invocation on mac3"
// try (MyAutoCloseable3 mac3 = new MyAutoCloseable3())
// {
// System.out.println( "try-with-resource MyAutoCloseable13" );
// }
System.out.println( "done" );
}
public static class MyAutoCloseable1 implements AutoCloseable
{
#Override
public void close()
{
System.out.println( "MyAutoCloseable1.close()" );
}
}
public static class MyAutoCloseable2 implements AutoCloseable
{
#Override
public void close() throws RuntimeException
{
System.out.println( "MyAutoCloseable2.close()" );
}
}
public static class MyAutoCloseable3 implements AutoCloseable
{
#Override
public void close() throws Exception
{
System.out.println( "MyAutoCloseable3.close()" );
}
}
}
You could check the JLS but there is actually a relatively easy reasoning why this is the only correct way the language should behave.
The main rule of checked exceptions is that any checked exception declared by a method must be handled, either by catching it or letting the calling method throw it.
The try-with-resources always (implicitly) calls the close method.
So if the specific close method of the AutoClosable you use (determined by the type declared in try) declares to throw a checked exception such as a SQLException you do need to handle this checked exception somewhere, otherwise it would be possible to violate the rule!
If the close method does not declare that it throws a checked exception, the rule is not violated and you do not need to handle a checked exception for implicitly calling the close method. It is actually a compilation failure if you do try to catch a checked exception that is never declared to be thrown.
Not every Java class (!) throws an exception. Sometimes you just want to use a try-with-resources to use the auto-close feature, and nothing else.
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
This the catch is optional because readLine() doesn't throw a (checked) exception.
Yes, close() could throw an exception, but the try-with-resources handles that too.
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
So this try-with-resources doesn't need a catch.
When a method throws and exception, do we need to have a try block inside the method?
For example,
public void foo() throws SomeException{
try{
// content of method
}
}
Is the try block required? Or, is the method able to throw a SomeException without it :
public void foo() throws SomeException{
// content of method
}
This is the case when we are not explicitly throwing a SomeException with throw.
If SomeException is a checked exception you have to either
Use a try{}catch block or
Declare that your method throws it.
You do not have to do both, either example you show in your question works just fine.
The difference is that with the try clause you handle the SomeException yourself, whereas by declaring that your own method throws it you delegate the responsability of handling the SomeException to the calling method.
When a method throws an exception it passes responsibility to handle exception to its caller.
So you don't need to handle exception if you throw it in your signature. Like as follows.
public void foo(){
try{
// content of method
}
}
but if you write it this way.
public void foo() throws SomeException{
}
you will call your method like as follows.
try{
foo();
}
You don't need a try block.
public void foo() throws SomeException {
// do some stuff
// you decide to throw the exception by yourself:
if (throwAnException) throw new SomeException();
// or you call a method that throws SomeExpection:
methodThatCanThrowSomeException();
// do more stuff
}
As long as you declare it in your signature, you're prefectly fine. The caller of your method has to handle the exception, not you. So a caller might do:
try {
foo();
} catch (SomeException e) {
// handle exception
}
Or he might pass it further along by himself.
The most problematic case you'll regularly encounter is calling a method that declares a checked exception. In the great majority of real-life cases it is not appropriate to handle that exception at the spot, but let it propagate upwards. Unfortunately, Java makes you redeclare this same exception all the way up, which creates clutter, exposes implementation details, and often also breaks the contracts of existing methods.
In such a case the way to proceed is to wrap and rethrow:
catch (RuntimeException e) {throw e;} catch (Exception e) {throw new RuntimeException(e);}
1. If the method that we are calling from a program throws an Exception, then we need to usetry/catch around the method invocation.
2. Suppose we are writing a method that throws an exception, then we need to throw new Exception object from withing the method.
3. An exception is an object of type Exception. We have Checked Exception, and Unchecked Exception (Runtime Exception).
you don't essentially need to have a try block in it
public void foo() throws SomeException {
// do some stuff
// you decide to throw the exception by yourself:
if (throwAnException) throw new SomeException();
// or you call a method that throws SomeExpection:
methodThatCanThrowSomeException();
// do more stuff
}
Can any of you explain what the differences are between throw, throws and Throwable and when to use which?
throws : Used when writing methods, to declare that the method in question throws the specified (checked) exception.
As opposed to checked exceptions, runtime exceptions (NullPointerExceptions etc) may be thrown without having the method declare throws NullPointerException.
throw: Instruction to actually throw the exception. (Or more specifically, the Throwable).
The throw keyword is followed by a reference to a Throwable (usually an exception).
Example:
Throwable: A class which you must extend in order to create your own, custom, throwable.
Example:
Official exception-tutorial
throw: statement to throw object t where t instanceof java.lang.Throwable must be true.
throws: a method signature token to specify checked exceptions thrown by that method.
java.lang.Throwable: the parent type of all objects that can be thrown (and caught).
See here for a tutorial on using exceptions.
This really easy to understand.
The java.lang.Throwable:
The Throwable class is
the superclass of all errors and
exceptions in the Java language. Only
objects that are instances of this
class (or one of its subclasses) are
thrown by the Java Virtual Machine or
can be thrown by the Java
throw statement.
Similarly, only this class or one of
its subclasses can be the argument
type in a catch clause.
More
The key word throws is used in method declaration, this specify what kind of exception[Throwable class] we may expect from this method.
The key word throw is used to throw an object that is instance of class Throwable.
Lest see some example:
We create ourself an exception class
public class MyException super Exception {
}
The we create a method that create a object from our exception class and throws it using key word throw.
private void throwMeAException() throws MyException //We inform that this method throws an exception of MyException class
{
Exception e = new MyException (); //We create an exception
if(true) {
throw e; //We throw an exception
}
}
When we are going to use method throwMeAException(), we are forced to take care of it in specific way because we have the information that it throws something, in this case we have three options.
First option is using block try and catch to handle the exception:
private void catchException() {
try {
throwMeAException();
}
catch(MyException e) {
// Here we can serve only those exception that are instance of MyException
}
}
Second option is to pass the exception
private void passException() throws MyException {
throwMeAException(); // we call the method but as we throws same exception we don't need try catch block.
}
Third options is to catch and re-throw the exception
private void catchException() throws Exception {
try {
throwMeAException();
}
catch(Exception e) {
throw e;
}
}
Resuming, when You need to stop some action you can throw the Exception that will go back till is not server by some try-catch block. Wherever You use method that throws an exception You should handle it by try-catch block or add the declarations to your methods.
The exception of this rule are java.lang.RuntimeException those don't have to be declared. This is another story as the aspect of exception usage.
throw - It is used to throw an Exception.The throw statement requires a single argument : a throwable class object
throws - This is used to specifies that the method can throw exception
Throwable - This is the superclass of all errors and exceptions in the Java language. you can throw only objects that derive from the Throwable class. throwable contains a snapshot of the execution stack of its thread at the time it was created
Throw is used for throwing exception, throws (if I guessed correctly) is used to indicate that method can throw particular exception, and the Throwable class is the superclass of all errors and exceptions in the Java
How to Throw Exceptions
Throw :
is used to actually throw the exception, whereas throws is declarative for the method. They are not interchangeable.
throw new MyException("Exception!);
Throws:
This is to be used when you are not using the try catch statement in your code but you know that this particular class is capable of throwing so and so exception(only checked exceptions). In this you do not use try catch block but write using the throw clause at appropriate point in your code and the exception is thrown to the caller of the method and is handled by it. Also the throws keyword is used when the function may throw a checked exception.
public void myMethod(int param) throws MyException
There are 2 main types of Exceptions:
Runtime Exceptions(unchecked): eg. NullPointerException, ClassCastException,.. Checked Exceptions: eg. FileNotFoundException, CloneNotSupportedException, ..
Runtime Exceptions are exceptions that occur at runtime and the developer should not try to catch it or stop it. You only write code to avoid them or issue a command throw, when the error criteria is met. We use throw inside the method body.
public Rational(int num, int denom){
if(denom <= 0) {
throw new IllegalArgumentException("Denominator must be positive");
}
this.num=num;
this.denom=denom;
}
However for Checked Exceptions, the JVM expects you to handle it and will give compiler error if not handled so you declare that it throws that type of exception as seen below in the clone() method.
Class Employee{
public Employee clone() throws CloneNotSupportedException{
Employee copy = (Employee)super.clone();
copy.hireDate = (Date)hireDate.clone();
return copy;
}
}
Same answer as above but with copy-paste pleasure:
public class GsonBuilderHelper {
// THROWS: method throws the specified (checked) exception
public static Object registerAndRun(String json) throws Exception {
// registering of the NaturalDeserializer
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Object.class, new NaturalDeserializer());
Gson gson = gsonBuilder.create();
Object natural = null;
try {
// calling the NaturalDeserializer
natural = gson.fromJson(json, Object.class);
} catch (Exception e) {
// json formatting exception mainly
Log.d("GsonBuilderHelper", "registerAndRun(json) error: " + e.toString());
throw new Exception(e); // <---- THROW: instance of class Throwable.
}
return natural;
}
}