Robert Klemme wrote:
}
This is common in Java, but it is incorrect.
What happens if init_resource() throws an exception?
Oops I forgot to mention that in finally {} one would check for resource not being nil. Corrected above.
The pattern is still broken - or put it differently: overly complex.
This is easier and as safe - and you can make the resource final and
avoid accidental reassignment:
final Resource res = initResource();
try {
res.use();
}
finally {
res.cleanup();
}
Actually, I have left Java 4 years back. However, that being my last programming language i still tend to thing in that way. IIRC, the above pattern is used commonly because most, if not all, books gave it in their samples. Take file opening or a database connection, for example.
Well, books are dead wood. You always have to apply your own reasoning. It is not too uncommon for multiple books repeating the same error. In my experience it is best to take every advice with a grain of salt and apply own reasoning.
Since it can throw a file not found exception, or a database connection etc exception, the JDBC tutorials will recommend:
declare db variable
try {
db = create_dbconnection(...)
db.use
}
catch (ex){}
finally { cleanup code }
Anyway, I'd like to ask, if I use your suggested pattern of opening a file or creating a resource before a begin/rescue/ensure block, would that not mean i am not trapping failures from that. (I am just unused to thinking this way! Could you point me to some code that illustrates this.
Since we did not talk about rescue clauses so far (apart from your example above) there was never exception handling - regardless of placement of ensure / finally blocks.
When using my pattern you can catch errors more selectively:
try {
Connection conn = getConnection();
try {
Statement st = conn.createStatement();
...
}
catch (SQLException e) {
System.err.println("Conn use error: " + e.getMessage());
}
finally {
close(conn);
}
}
catch (SQLException e) {
System.err.println("Conn init error: " + e.getMessage());
}
If you do not like the nesting you can refactor and extract the inner part into another method.
Also, is there a quick way to know what exceptions a method can throw ? Or is that not relevant ?
In Ruby: No, you would have to look at the code of a method and all methods which were called etc. Documentation is the fastest way I know of.
In Java: all methods can throw sub classes of all the checked exceptions listed in the signature plus all sub classes of RuntimeException and Error.
Kind regards
robert
···
On 05.10.2008 18:31, Nit Khair wrote:
On 02.10.2008 14:48, Nit Khair wrote: