Lets say I have a class that has two OutputStream members:
public class A {
OutputStream os1 = ...
OutputStream os2 = ...
...
}
Now, in this class, I have a cleanup() method which must at least attempt to close both streams:
public void cleanup() throws IOException {
try {
os1.close();
} finally {
os2.close();
}
}
Now, I'm confident that the above code will try to close both streams, but what is interesting is what happens when both calls to close() throw an IOException. I want to say that the exception from os2 will propogate upward, but perhaps the behavior is undefined. I've done some googling but I'm not finding anything that answers this question well.
The JLS §14.20.2 describes the behaviour.
The exception, that is thrown by the method is the exception caused by os2.close().
If the finally throws an exception, then the method terminates with that exception. It's very well defined behavior. Likewise, if a finally returns, then the method returns with the finally's return value, regardless of any previous return from the associated try block.
Yes, the second exception is propagated upwards, and the first exception is lost.
But if you're using Java 7 or better, it's far better to use the "try with resources" syntax. The code is much cleaner, there's a lot less to write, and it'll do a far better job than you can of making sure the resources get closed when they should, no matter what. For example, no matter how smart and fancy you make cleanup(), if it doesn't get called then you're out of luck. What if the context that's supposed to call it itself throws an exception? Don't do it that way!
Related
please explain the the difference between return exceptions and throw exceptions?
I see some programs use return new IOException() and the throw new IOException(). Why we use return statement, in that moment the method which included above return statement, is stop the execution?
please explain the the difference between return exceptions and throw exceptions.
The difference is this:
Throwing an exception is the normal thing to do. It changes the flow of control.
Returning an exception is legal, but unusual. It does not change the flow of control1.
1 - ... except in the sense that any return statement does this. The JLS talks about execution of a statement completing normally or completing abruptly. If you want the full details, read JLS 14.1.
However ....
return new SomeException(...);
.... is a rather dubious thing to do. The only reasonable use-case I can think of is if your code is using these exception objects to flag multiple errors, and something else is collecting and reporting them. You might do this if you needed to capture the stack traces for the locations where errors were detected. But if not, using exceptions like this is simply ugly and inefficient.
Why we use return statement, in that moment the method which included above return statement, is stop the execution?
No. Returning an exception is no different to returning any other value. It does not stop execution.
If you showed us an example of (real) application code that does this, we could have a go at explaining it.
Throwing exception means something is wrong and you have to try-catch the execution or it will stop the thread.
On the other hand returning an exception means nothing happened wrong. You are just creating an object (like any other objects). You still need to throw that exception object to let the program know that the exception happened.
Let's say you want an exception like Device is not ready. Now you can keep a method to create that exception like this,
public Exception getMyException() {
return new Exception("Device is not ready yet.");
}
To make use of that exception you need to call that method and throw the exception like below,
public void checkFile() {
if(...check device status is not ready ...) {
throw getMyException();// or you could use any built-in ex like new IOException("....");
}
}
In the Advantages of Exceptions section of the Java™ tutorials:
A method can duck any exceptions thrown within it, thereby allowing a method farther up the call stack to catch it.
[...]
...ducking an exception requires some effort on the part of the middleman methods. Any checked exceptions that can be thrown within a method must be specified in its throws clause.
What does "duck an exception" mean here? I searched the web and FOLDOC (Free On-line Dictionary of Computing) but didn't find anything that looked promising.
Well, ducking simply means to lower your head in order to avoid being hit or seen. In this case, 'duck an exception' just means avoiding your code from getting hit by an exception.
For your method not to be hit by exception, you throw it further up the call stack by declaring a throws exception on your method
public void myMethod() throws IOException {
}
If you don't duck, you have to catch it:
public void myMethod() {
try {
// ...
} catch(IOException e) {
// handle exception
}
To "duck an exception" means "not handle the exception". This actually explains the name: to duck means to "To evade; dodge".
The method ducking the exception simply doesn't handle it (because, for example, it is not its purpose) and let the exception be thrown to the calling method.
For example, consider a method whose purpose is to count the number of lines in a file. This would be a simple implementation (Java 8):
private static long numberOfLines(Path path) throws IOException {
try (BufferedReader br = Files.newBufferedReader(path)) {
return br.lines().count();
}
}
Note that this method doesn't handle the IOException that is thrown by Files.newBufferedReader(path), because that's not the method goal. It ducks and let the caller handle it appropriately.
Note the caller might also duck the exception and let its caller handle it, etc.
i think it means a method can catch an exception and re-throw it for other method to catch it and handle it as needed. Or just throw a new exception. Or avoid catching an exception and let it bubble up the call stack. The point is to have a method delegate exception handling to other method which might be more appropriate to handle a given exception (e.g by having access to necessary data and/or state). But (for java) this requires declaring methods with throws clause all the time, which becomes boilerplate easily
as mentioned in #jmcg's comment, literally "DUCK simply means to lower your head in order to avoid being hit or seen" (like ducks do in a river)
I think to duck means re-throw an exception... in other words, ignore it hoping that someone else will handle it :)
I have a method throws an Exception
public int myMethod throws Exception
I have another function calls myMethod function and hava try-catch block.
I throws a runtime exception to enforce the program to be terminated.
Is this a proper way to terminate the program? If I do this way, it prints the stack trace twice and the stack trace from RuntimeException is useless.
What is the suggested way to terminate program in catch clause with printing the full stack trace.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
throw new RuntimeException();
}
}
The answer is "it depends".
If this code is part of the application itself then calling System.exit(int) is possibly the best option. (But if the application is "failing", then you should call exit with a non-zero return code. Zero conventionally means "succeeded".)
However, if there is a significant possibility that this code is going to be embedded / reused in a larger Java application, calling System.exit(...) is problematic. For instance a library that calls System.exit(...) when something bad happens is going to cause havoc for an application that uses it.
For something like that, you might throw a custom runtime exception which you catch and handle specifically in your main method. (If I was doing that, I'd pass the Exception as a constructor parameter to the custom exception ... and make it the cause exception. And I wouldn't print it / log it at that point.)
(Calling System.exit(...) also causes problems when you are unit testing ... 'cos the call will most likely pull the plug on the JVM running the test suite!)
The other point is that catch (Exception ...) is almost always a BAD IDEA. The point is that this catches just about everything (including all sorts of things that you never dreamed could happen!) and buries them. It is far better to catch the specific exceptions you are expecting (e.g. checked exceptions) and can deal with ... and just let the rest propagate in the normal way.
If you are stuck with catch (Exception ...) because you are using something that is declared as throwing Exception, the best way to deal with it is to change the throws Exception. And the sooner the better. Change the throws Exception to declare a list of (more) specific exceptions that you expect to be thrown by the method.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
System.exit(0); // terminates with exit code 0, no extra stack trace.
}
}
Exception handling is one of the most important aspects in programming.
The answer for your question depends on what type of application you are working on.
system.exit(0) will just terminate your program and this can create a lot of havoc .
Also make sure that you never catch Exception , if you are doing that then you are catching all the types of exceptions which you may not intend to handle also.
Always catch Specific exception such that it gives you opportunity to handle it in a manner which you need.
In one of my Java application's code, I have a try-catch-finally block in which the try block creates some input and output streams and if something goes wrong I close any earlier opened streams in finally.
finally
{
if(inputStream != null)
inputStream.close();
if(outputStream != null)
outputStream.close();
}
But the <stream>.close() line in Eclipse shows error that "Unhandled exception IOException" in the code for this line and shows that the solution is to include another try/catch in the finally block which would seem to be bad as a programming practice and I don't want in finally block.
My question is: is it possible to remove this error in Eclipse and use try/catch only when I need it instead of eclipse telling me to do the try/catch add. (Since I am already trying to avoid exception by replacing try/catch with if/else as possible).
This is not an Eclipse error, it is a Java compiler error. Eclipse is merely reporting the Java compilation error for you. There is no way to "turn it off" as the code does not compile without the try/catch clause. It is a safety feature in Java that forces you to handle commonly thrown Exceptions.
Methods have Exceptions in their signature. For example, InputStream.close() throws an IOException, forcing you to handle it in a try/catch block.
public void close() throws IOException {
...
Throwing an Exception is a way of telling the program that a significant problem - that must be handled - has occurred.
My question is: is it possible to remove this error in eclipse and use try/catch when I need it otherwise not instead of eclipse telling me to do try/catch add.
No, it is not possible.
(Since I am already trying to avoid exception by replacing try/catch with if/else as possible).
You should generally never try to replace try/catch blocks with if/else blocks. They are two distinct features with distinct purposes.
Exceptions are an essential Java feature. Read about it and understand it.
Properly this should be done something like this to ensure that we attempt to close both streams.
finally
{
try {
if(inputStream != null)
inputStream.close();
}
catch(Exception e)
{ /* Ignore */ }
try {
if(outputStream != null)
outputStream.close();
}
catch(Exception e)
{ /* Ignore */ }
}
If you don't care about handling the exception, check out the Apache commons io library.
org.apache.commons.io.IOUtils.closeQuietly(inputstream)
Works for outputstream, writer and reader too.
IOException is not something that you can avoid because it might happen because of circumstances outside your control. (Broken network connection, hard drive error etc). Eclipse is totally right that inputStream.close() and outputStream.close() itself may throw exception, and you must be prepared to handle that somehow. There is no way to silence this error because it is not Eclipse's pickiness; your code is not valid Java code as it stands.
You may declare that your function throws IOException and delegate the handling of the exception to the caller, or you must bite the bullet and handle (and probably ignore) the IOException yourself. I think there is a utility function in the IOUtils library of Apache Commons that encapsulates this logic, which would make your code cleaner (and hide the fact that you are silently ignoring an IOException).
But the .close() line in eclipse shows error that Unhandled exception IOException in code for this line and shows solution to include another try/catch in finally block which is bad as programming practice and i don't want in finally block.
The fact that close methods can also throw IOExceptions, so that you have to have nested try/catch clauses inside the finally block, is an unfortunate situation.
But there is really nothing much you can do about this. You need those (ugly) finally blocks to handle exceptions properly.
There is nothing wrong with eclipse.It just show you have a compile error in your code.you cannot replace try-catch with if-esle and here it required try catch.You need this try catch not because the input stream may be null as you try in if else.
I keep getting stuck conceptually on deciding an Exception-handling structure for my project.
Suppose you have, as an example:
public abstract class Data {
public abstract String read();
}
And two subclasses FileData, which reads your data from some specified file, and StaticData, which just returns some pre-defined constant data.
Now, upon reading the file, an IOException may be thrown in FileData, but StaticData will never throw. Most style guides recommend propagating an Exception up the call stack until a sufficient amount of context is available to effectively deal with it.
But I don't really want to add a throws clause to the abstract read() method. Why? Because Data and the complicated machinery using it knows nothing about files, it just knows about Data. Moreover, there may be other Data subclasses (and more of them) that never throw exceptions and deliver data flawlessly.
On the other hand, the IOException is necessary, for if the disk is unreadable (or some such) an error must be thrown. So the only way out that I see is catching the IOException and throwing some RuntimeException in its place.
Is this the correct philosophy?
You're right.
The exception should be at the same level of abstraction where is used. This is the reason why since java 1.4 Throwable supports exception chaining. There is no point to throw FileNotFoundException for a service that uses a Database for instance, or for a service that is "store" agnostic.
It could be like this:
public abstract class Data {
public abstract String read() throws DataUnavailableException;
}
class DataFile extends Data {
public String read() throws DataUnavailableException {
if( !this.file.exits() ) {
throw new DataUnavailableException( "Cannot read from ", file );
}
try {
....
} catch( IOException ioe ) {
throw new DataUnavailableException( ioe );
} finally {
...
}
}
class DataMemory extends Data {
public String read() {
// Everything is performed in memory. No exception expected.
}
}
class DataWebService extends Data {
public string read() throws DataUnavailableException {
// connect to some internet service
try {
...
} catch( UnknownHostException uhe ) {
throw new DataUnavailableException( uhe );
}
}
}
Bear in mind that if you program with inheritance in mind, you should design carefully for the specific scenarios and test implementations with those scenarios. Obviously if it is harder to code an general purpose library, because you don't know how is it going to be used. But most of the times applications are constrained to an specific domain.
Should your new exception be Runtime or Checked? It depends, the general rule is to throw Runtime for programming errors and checked for recoverable conditions.
If the exception could be avoided by programming correctly ( such as NullPointerException or IndexOutOfBounds ) use Runtime
If the exception is due to some external resource out of control of the programmer ( the network is down for instance ) AND there is something THAT could be done ( Display a message of retry in 5 mins or something ) then a checked exception should be used.
If the exception is out of control of the programmer, but NOTHING can be done, you could use a RuntimeException. For instance, you're supposed to write to a file, but the file was deleted and you cannot re-create it or re-try then the program should fail ( there is nothing you can do about it ) most likely with a Runtime.
See these two items from Effective Java:
Use checked exceptions for recoverable conditions and run-time exceptions for programming errors
Throw exceptions appropriate to the abstraction
I hope this helps.
If you're not explicitly stating that read() can throw an exception, then you'll surprise developers when it does.
In your particular case I'd catch the underlying exceptions and rethrow them as a new exception class DataException or DataReadException.
Throw the IOException wrapped in an exception type that is appropriate to the "Data" class. The fact is that the read method wont always be able to provide the data, and it should probably indicate why. The wrapping exception may extend RuntimeException and therefore not need to be declared (although it should be appropriately documented).
Use Runtime Exceptions, combined with an exploding catch-all at the top. It's a bit scary at first, but gets better once you get used to it.
In my web applications, everything thrown is Runtime. There are almost no "throws" clauses, and I only have catchblocks in places I really can (or want) to handle the exception. At the highest level, there is a catch Throwable which renders a technicall error page, and writes a log entry.
A Log4J mailer sends me the log entry and 10 log entries preceding it. So when the client calls, I usually already know that there was a problem.
With proper (unit)testing and clean programming, the added cleanliness and readability outweighs the loss of checked exceptions anytime.
You should declare some kind of exception on the abstract read() method. The abstract class is effectively declaring an interface - and you already know from your two concrete subclasses that an implementation may well be unable to return successfully due to an exception condition.
Thus declaring some exception to be thrown in the abstract Data.read() method is entirely correct. Don't be tempted to simple declare that it throws IOException, as it shouldn't be tied to and of the specific implementations (else you'd have to declare that it could throw SQLException too in case you ever decide to have a database-reading subclass, SAXException in case you ever have an XML-based reader (that uses SAX), and so on). You'll need a custom exception of your own that adequately captures this at the abstract level - something like the DataException recommended above, or potentially reuse an existing custom exception from the same package if this makes sense.