One thing to note. The "fact" that a PreparedStatement is optimized for reuse may or may not be true on the backend database. In some cases, when you issue a prepareStatement a query plan for that statement is built in the database engine, all ready to run. But query plans take up space and if the database is heavily used your plan may get flushed before you even get a chance to use it.
Also, some JDBC implementations have a default behavior of not even building the query plan (jConnect, Sybase's JDBC driver, is an example of this). They basically ignore the prepareStatement and treat the thing like any other statement (note that with jConnect you *can* force it to actually prepare the statement by setting a property when you build the connection - see Sybase's documentation).
Having said that, I find PreparedStatements easier to work with from a programming aspect. It would be nice though, for debugging, if there were an easy way of getting back as a String the SQL that was actually executed, parameters and all.