Re: How to initialise a final static String array

Discussion in 'Java' started by Arne Vajhøj, Mar 18, 2012.

  1. Arne Vajhøj

    Arne Vajhøj Guest

    On 3/18/2012 8:55 AM, Cecil Westerhof wrote:
    > I want to use final for my static variables. I now do for example:
    > private static final Connection conn;
    > private static final Combo container;
    >
    > and
    > static {
    > Connection tempConn;
    > Statement tempStmt;
    > try {
    > Class.forName("org.h2.Driver");
    > tempConn = DriverManager.getConnection(
    > "jdbc:h2:tcp://localhost/~/databases/stock", "sa", "");
    > tempStmt = tempConn.createStatement();
    > } catch (Exception e) {
    > tempConn = null;
    > tempStmt = null;
    > }
    > conn = tempConn;
    > stmt = tempStmt;
    >
    > and
    > if (conn == null) {
    > throw new Exception("Could not initialise");
    > }
    >
    > The only problem I have is with my array of String.
    > I now have:
    > private static final String[] titles = {
    > "Stock",
    > "Number",
    > "Dare",
    > "Container"
    > };
    >
    > Because when I put it in the static block I get an error.
    > Beside this I can execute a statement like:
    > titles[0] = "changed";
    >
    > Can I get the initialisation in the static part? And in such a way
    > that the elements can not be changed?


    Other have already explained what you can not and what you can.

    I will just add that you should carefully evaluate whether
    you really want a class with a static field with a
    database connection. In almost all cases it is a disaster
    waiting to happen.

    Arne
    Arne Vajhøj, Mar 18, 2012
    #1
    1. Advertising

  2. Arne Vajhøj

    Lew Guest

    On 03/18/2012 09:20 AM, Arne Vajhøj wrote:
    > On 3/18/2012 8:55 AM, Cecil Westerhof wrote:
    >> I want to use final for my static variables. I now do for example:
    >> private static final Connection conn;
    >> private static final Combo container;
    >>
    >> and
    >> static {
    >> Connection tempConn;
    >> Statement tempStmt;
    >> try {
    >> Class.forName("org.h2.Driver");
    >> tempConn = DriverManager.getConnection(
    >> "jdbc:h2:tcp://localhost/~/databases/stock", "sa", "");
    >> tempStmt = tempConn.createStatement();
    >> } catch (Exception e) {
    >> tempConn = null;
    >> tempStmt = null;
    >> }
    >> conn = tempConn;
    >> stmt = tempStmt;
    >>
    >> and
    >> if (conn == null) {
    >> throw new Exception("Could not initialise");
    >> }
    >>
    >> The only problem I have is with my array of String.
    >> I now have:
    >> private static final String[] titles = {
    >> "Stock",
    >> "Number",
    >> "Dare",
    >> "Container"
    >> };
    >>
    >> Because when I put it in the static block I get an error.
    >> Beside this I can execute a statement like:
    >> titles[0] = "changed";
    >>
    >> Can I get the initialisation in the static part? And in such a way
    >> that the elements can not be changed?

    >
    > Other have already explained what you can not and what you can.
    >
    > I will just add that you should carefully evaluate whether
    > you really want a class with a static field with a
    > database connection. In almost all cases it is a disaster
    > waiting to happen.


    As I stated in an answer to the other multipost of this message:

    Cecil Westerhof wrote:
    > I want to use final for my static variables. I now do for example:
    > private static final Connection conn;


    DO NOT USE TAB CHARACTERS TO INDENT USENET POSTS.

    Use spaces, up to four per indent level.

    > private static final Combo container;
    >
    > and
    > static {
    > Connection tempConn;
    > Statement tempStmt;
    > try {
    > Class.forName("org.h2.Driver");
    > tempConn = DriverManager.getConnection(
    > "jdbc:h2:tcp://localhost/~/databases/stock", "sa", "");
    > tempStmt = tempConn.createStatement();
    > } catch (Exception e) {
    > tempConn = null;
    > tempStmt = null;
    > }
    > conn = tempConn;
    > stmt = tempStmt;


    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.

    > and
    > if (conn == null) {
    > throw new Exception("Could not initialise");


    What kind of exception /should/ you throw? Not 'Exception'.

    > }
    >
    > The only problem I have is with my array of String.
    > I now have:
    > private static final String[] titles = {
    > "Stock",
    > "Number",
    > "Dare",
    > "Container"
    > };
    >
    > Because when I put it in the static block I get an error.


    That doesn't make sense. It's a perfectly legitimate initialization.

    http://sscce.org/
    please.

    --
    Lew
    Honi soit qui mal y pense.
    http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
    Lew, Mar 18, 2012
    #2
    1. Advertising

  3. On 3/18/2012 1:31 PM, Lew wrote:
    > On 03/18/2012 09:20 AM, Arne Vajhøj wrote:
    >> On 3/18/2012 8:55 AM, Cecil Westerhof wrote:
    >>> I want to use final for my static variables. I now do for example:
    >>> private static final Connection conn;

    ....
    >> Other have already explained what you can not and what you can.
    >>
    >> I will just add that you should carefully evaluate whether
    >> you really want a class with a static field with a
    >> database connection. In almost all cases it is a disaster
    >> waiting to happen.

    >
    > As I stated in an answer to the other multipost of this message:


    cljh?

    > 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.

    Arne
    Arne Vajhøj, Mar 18, 2012
    #3
  4. Arne Vajhøj

    Lew Guest

    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
    Lew, Mar 19, 2012
    #4
  5. On 3/19/2012 1:16 AM, Lew wrote:
    > 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.


    Exceeding max connections is certainly a potential problem.

    But there is also the thread safety issue.

    > 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.


    The new try syntax in Java 1.7 is somewhat that.

    Arne
    Arne Vajhøj, Mar 21, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JFCM
    Replies:
    4
    Views:
    5,734
  2. Yu
    Replies:
    12
    Views:
    483
    vijay
    Jul 10, 2003
  3. Leslaw Bieniasz
    Replies:
    1
    Views:
    334
    mlimber
    Apr 5, 2006
  4. Eric Sosman
    Replies:
    0
    Views:
    578
    Eric Sosman
    Mar 18, 2012
  5. Joost Kraaijeveld
    Replies:
    2
    Views:
    1,388
Loading...

Share This Page