Re: How to initialise a final static String array
 
Arne Vajh??j wrote:
Lew wrote:
Static JDBC connections, and especially static JDBC statements, are a
very bad idea.
Very bad.
Statements should be local in scope, not even instance level. (Usually.)
Even connections should only be instance members if you have rather
short-lived objects holding them.
At least in the server world with connection pools.
For a desktop app I would say that it depends on the specific app.
Fair enough.
The overarching point being to consider thoughtfully the various issues of 
scope and lifetime as you construct your implementation.
Even with connection pools the usual perspective for connections' consumers is 
virtual exclusivity. The client pretends it has exclusive access to the 
connection as if it were brand new from the time of the client's acquisition 
of the connection and unsullied by anyone else until its release. The pool 
manager works hard to give the client this illusion.
In such a world view, the client holds the same responsibilities to manage 
connection lifetime regardless of the underlying mechanism.
In most practical systems, a connection is a rather precious resource. The 
very word "resource" in computer systems means something that must be managed, 
of limited availability, that must be released when not needed, in short, 
something precious.
That's why a static resource is often poisonous. It lasts as long as the 
class, and might never formally be released. And it risks reuse in 
inappropriate scenarios.
An instance-level connection that lives as long as its containing object is an 
interesting idiom. It works to hide messy acquisition/release mechanics from 
its own clients.  From a lifetime standpoint. it only defers the timing 
decision to the next client up the chain.
At some level, the connection must be acquired. Like matching parentheses, 
each acquisition must pair with a resource release, somehow, somewhen.
The guarantee of such release is the province of the 'finally' block. Making 
the proper guarantees can be rather verbose at times, but are worth it in 
system reliability and scalability. (When such considerations apply. But even 
when they don't, the same idioms are simple enough that there's no reason to 
avoid them.) Such pairing of resource acquisition with reliable release is 
best done (again, usually) with local variables.
You control lifetime to the time of the service, from request to response. (I 
just laid a whole world of assumption about service architecture under that 
one sentence.)
Sure, the notion isn't truly universal. But if you understand this 
architecture, you can readily understand Arne's comment and why the scenario 
he proposed doesn't need the safety of such idioms. He understands lifetime to 
know why class-level works in that situation.
I have a ritualistic approach to certain programming layers. For resources 
it's what's officially called RAII (Resource Acquisition Is Initialization), 
but I call RRID (Resource Released If Destroyed). Java doesn't support this 
intrinsically, so to use it you wrap resources in a guaranteed 
release-when-done idiom.
Here's a rough, never-compiled example. It's rather formal, but it does seem 
to guard against the crap. (All the missing stuff left as an exercise for the 
reader.)
package eegee.query;
import apache.log4j.Logger;
import static apache.log4j.Logger.getLogger;
import eegee.connection.Connection;
import static eegee.connection.Connection.getManager;
import eegee.entity.Entity;
import eegee.entity.Key;
import static eegee.entity.Entity.ENTITY_QUERY;
public class RridIdiomizer
{
   private static final Connection.Manager manager = getManager();
   private final Logger logger = getLogger(getClass());
   public Entity lookUp(Key key)
   {
     final Connection cxn;
     try
     {
       cxn = manager.acquireConnection();
     }
     catch (IOException exc) // no need for RRID if nothing acquired
     {
       final String msg = "lookup() connection failure";
       logger.error(msg, exc);
       throw new IllegalStateException(msg, exc);
     }
     assert cxn != null; // I love assertions, but they're subtle
     // here's the RRID - perforce release 'cxn' ere it leave scope
     try
     {
       Entity entity = cxn.prepareQuery(ENTITY_QUERY, key).execute();
       return entity;
     }
     catch (IOException exc)
     {
       final String msg = "lookup() query failure";
       logger.error(msg, exc);
       throw new IllegalStateException(msg, exc);
     }
     finally // the RRID part
     {
       cxn.close();
     }
   }
}
-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg