Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #13035 > unrolled thread

How to initialise a final static String array

Started byCecil Westerhof <Cecil@decebal.nl>
First post2012-03-18 13:55 +0100
Last post2012-03-20 20:01 -0400
Articles 8 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  How to initialise a final static String array Cecil Westerhof <Cecil@decebal.nl> - 2012-03-18 13:55 +0100
    Re: How to initialise a final static String array Jeff Higgins <jeff@invalid.invalid> - 2012-03-18 09:25 -0400
    Re: How to initialise a final static String array Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-03-18 09:24 -0400
    Re: How to initialise a final static String array Arne Vajhøj <arne@vajhoej.dk> - 2012-03-18 12:20 -0400
      Re: How to initialise a final static String array Lew <noone@lewscanon.com> - 2012-03-18 10:31 -0700
        Re: How to initialise a final static String array Arne Vajhøj <arne@vajhoej.dk> - 2012-03-18 19:04 -0400
          Re: How to initialise a final static String array Lew <noone@lewscanon.com> - 2012-03-18 22:16 -0700
            Re: How to initialise a final static String array Arne Vajhøj <arne@vajhoej.dk> - 2012-03-20 20:01 -0400

#13035 — How to initialise a final static String array

FromCecil Westerhof <Cecil@decebal.nl>
Date2012-03-18 13:55 +0100
SubjectHow to initialise a final static String array
Message-ID<87vcm2vzje.fsf@Compaq.site>
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?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [next] | [standalone]


#13036

FromJeff Higgins <jeff@invalid.invalid>
Date2012-03-18 09:25 -0400
Message-ID<jk4nlu$gga$1@dont-email.me>
In reply to#13035
On 03/18/2012 08: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?
>
<http://www.ibm.com/developerworks/java/library/j-jtp1029/index.html#limitations>

[toc] | [prev] | [next] | [standalone]


#13037

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-03-18 09:24 -0400
Message-ID<jk4nn9$gv1$1@dont-email.me>
In reply to#13035
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.

     Works fine for me. What error do you get?

> Beside this I can execute a statement like:
> 		titles[0] = "changed";

     Yes.  The identifier `titles' is final, and will always refer
to the same String[] array: You cannot set it to null or make it
refer to some other String[] array.  But the String[] array itself
is just like any other array: You can change the contents of its
elements any time you like.

> Can I get the initialisation in the static part? And in such a way
> that the elements can not be changed?

     To the first: Yes, certainly.  To the second: No, Java arrays
are always mutable.

     Nonetheless, there are a few things you can do to work around
some of the issues with array mutability.  If you're worrked about
exposing the array to external code that might muck with it, you
could keep the original array `private' (as you've done) and export
a throw-away copy instead:

	public String[] getTitles() {
	    return titles.clone();
	}

Or you could export an immutable List instead of the array:

	public List<String> getTitles() {
	    return Collections.unmodifiableList(
	        Arrays.asList(titles));
	}

If you're worried that you yourself might accidentally damage the
array, you could even use the List internally:

	private static final List<String> titles =
	    Collections.unmodifiableList(
	        Arrays.asList(
	            "Stock", "Number", "Dare", "Container"));

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#13038

FromArne Vajhøj <arne@vajhoej.dk>
Date2012-03-18 12:20 -0400
Message-ID<4f660b33$0$288$14726298@news.sunsite.dk>
In reply to#13035
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



[toc] | [prev] | [next] | [standalone]


#13039

FromLew <noone@lewscanon.com>
Date2012-03-18 10:31 -0700
Message-ID<jk564u$2f4$2@news.albasani.net>
In reply to#13038
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

[toc] | [prev] | [next] | [standalone]


#13040

FromArne Vajhøj <arne@vajhoej.dk>
Date2012-03-18 19:04 -0400
Message-ID<4f666a03$0$293$14726298@news.sunsite.dk>
In reply to#13039
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

[toc] | [prev] | [next] | [standalone]


#13044

FromLew <noone@lewscanon.com>
Date2012-03-18 22:16 -0700
Message-ID<jk6fg9$tmn$1@news.albasani.net>
In reply to#13040
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

[toc] | [prev] | [next] | [standalone]


#13093

FromArne Vajhøj <arne@vajhoej.dk>
Date2012-03-20 20:01 -0400
Message-ID<4f691a54$0$294$14726298@news.sunsite.dk>
In reply to#13044
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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web