ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button
Article:
  10 Reasons We Need Java 3.0
Subject:   Almost forgot... Connection.close() throws SQLException :-(
Date:   2004-01-14 11:36:22
From:   anonymous2
How about non-inheritable public static methods for Interfaces?


One thing that's always annoyed me is the hard division between abstract classes and interfaces. Abstract classes obviously can't be multiply inherited, and interfaces aren't allowed to contain methods.


But wait a second... interfaces ARE allowed to contain public static final objects! So why not public static final methods too? Such methods would NOT be inherited by implementing objects or Interfaces extending the original. Essentially, it would be a convenient way to package utility methods without getting tangled up in the evils of multiple inheritance. And I can think of one GREAT place to start using them first... java.sql.Connection.


To just about everyone's great annoyance, Connection.close() throws SQLException. OK, yes, there are cases where you'd want to catch an exception thrown while closing a connection where, say, commits happen only upon closure. On the other hand, they make a HUGE mess with cleanup code, like the following:


Connection conn = null;
try {
conn = myDataSource.getConnection();
// ... do stuff
}
catch (SQLException e) {
// most likely due to error with Statement or ResultSet...
}
finally {
try {
if (connection != null) { conn.close(); }
}
catch (SQLException shutUpAlready) {}
}


What Sun SHOULD have done is to make a second SQL-related Exception -- SQLRuntimeException -- and made Connection.close() throw THAT one instead. Then, people who need to care about catching exceptions that indicate transaction failure could do it, but people just trying to clean up the connections inside a finally {} block while the rest of the class goes down in flames wouldn't have to go through the idiocy of having a try/catch block inside a finally block.


Now, as for the changes I'd want Sun to make to Connection:


public interface Connection {

// interface definitions go here

// added by Sun...
public static Throwable close(Connection conn) {
try {
conn.close();
}
catch (Throwable t) {
return t;
}
}
}


According to the proposed rules, Connection.close() would ONLY be callable as... Connection.close(). It wouldn't be inherited by Connection-implementing objects. So if class Foo implements Connection, and 'bar' is a Foo object, the following would be invalid:


Foo.close(bar);
bar.close(bar);


Of course, Foo's creator could always write his own public static close(Connection) method, but it would have nothing whatsoever to do with Connection's, nor would it be inherited by Foo-implementing objects any more than Connection's method would be inherited by Connection-implementing objects. So bar.close(bar) would be invalid in any case, as would a call to this.close(Connection) from within a Connection-implementing object.