Forums Register Login

Using final as program-wide variables

+Pie Number of slices to send: Send
I want to be able to set up static variables for my program to use, and are also final.

The values for the variables are read at the start of runtime from a file.

The problem I am having is that I get compile errors saying that my final variables might not have been initialized. Here is an example of what I am trying to do.





This is obviously wrong, but I do not see how. final variables in Java can never change its value, but it doesn't have to have a value assigned when it is declared.

Any help is appreciated!
+Pie Number of slices to send: Send
In fact finaly variables have to have a value in compilation time. That�s because the don�t truly exist as variables, but they are actual final values and are not references to a value, they are a value.
If you want to assign a new value. Then it is not final. As far as I understand in your code, the static part is right because you are using it as a class wide configuration and not an instance property. But in the moment you try to change/assign a new value to the property it is in conflict with the final concept.
+Pie Number of slices to send: Send
Actually I am using them as program wide variables, not just in the class. Is this the way to go about it?

I guess it doesn't have to be final since the variables are unique to this program. Are there security issues with having these variables public and not final? This is going to be a server app.
+Pie Number of slices to send: Send

Note that this is not a constant - merely, a final. It is also not a "final variable", since "final" and "variable" are oxymoronic (the JLS teaches otherwise unfortunately).

A final does not necessarily have to be assigned inline, in an initializer or at all. A final field however, must be assigned. A final local must be "definitely assigned" before its use - meaning if it is never used, it may not necessarily ever be assigned.

The difference between a final and a constant is clearly demonstrated here: http://jqa.tmorris.net/GetQAndA.action?qids=13&showAnswers=true
+Pie Number of slices to send: Send
No offense, but I will take the word of the JLS and Head Start Java, over a single poster who can't reference an authorative source. I am not flaming, it just takes more to convince me.

Yes, constant variable is an oxymoron but is a term that is in use not just for Java, and is widely and easily understood.

Anyway, is my approach(minus the final modifier) a good way to store program-wide variables.
[ May 20, 2006: Message edited by: Steve L. Williams ]
+Pie Number of slices to send: Send
Steve, I hope it's just the comment about "final variable" that you're disagreeing with, because the rest of what he says is completely in agreement with the JLS. See 15.28 in particular. The JLS use of the term "variable" can be a bit... odd, certainly, and there are many other authorities that would define it differently. However it's certainly useful to understand the JLS definition for purposes of understanding the JLS itself, at least.

[Steve]: Anyway, is my approach(minus the final modifier) a good way to store program-wide variables.

Mmm, it will work, but I'd favor using a static initializer as Tony showed. That way you can keep the final modifier, which helps guard against unexpected bugs if someone tries to change the behavior later.
+Pie Number of slices to send: Send
According to everything I have read static final variables are constants. Perhaps I misread I got severely annoyed when he tried to make his point by self-referencing.

I looked at his approach, but the variables values are not known at compile time, is this still going to work?
[ May 20, 2006: Message edited by: Steve L. Williams ]
+Pie Number of slices to send: Send
[Steve]: According to everything I have read static final variables are constants.

Ah, I see that I forgot they went and moved part of the definition in JLS3 that used to be in 15.28 - the other part is at JLS3 4.12.4. "We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (�15.28) a constant variable." You're not initializing the variable with a compile-time constant expression, therefore it's not a constant variable. And it doesn't fall under any of the other categories listed in 15.28 for a constant expression, therefore it's not a constant expression.

[Steve]: I looked at his approach, but the variables values are not known at compile time, is this still going to work?

As I already said, yes it will work (without benefit of the final modifier). However you seem to be overlooking the idea that "whateverYouWant" includes the possibility of reading from a file. You'll need a try/catch block for the IOException, but otherwise, no problem.
[ May 20, 2006: Message edited by: Jim Yingst ]
+Pie Number of slices to send: Send
 

Originally posted by Steve L. Williams:

Anyway, is my approach(minus the final modifier) a good way to store program-wide variables.



It's generally a questionable idea to have program-wide variables at all. (Assuming that by "program-wide" you mean that those static fields are directly accessed from all kinds of places in your program.)

The reason is that such global variables cause strong coupling between your classes. Every time you need to change how such a variable works, all classes that directly access need to be checked and retested to see whether they still work. It also reduces the possibility to reuse the classes that access them in different contexts, and makes unit testing much harder.

The alternative is to pass the values around instead. That might sound like a lot more work to you. But you need to remember that the most work is done not while initially writing the first version of a program, but while maintaining and extending it. And a well decoupled design is essential for that work.
+Pie Number of slices to send: Send
I agree with Ilja on this. But just to undermine his point , I offer one other way to fulfil the original goal of initializing a static final:

This is very much like using a static block. But I find that some people will overlook or misunderstand a static block, whereas they're more likely to see and understand a named method. So this may be more readable to a wider range of programmers. Also by explicitly naming the method, we can more easily test it. (Though at the moment it's final, that can be changed.) And we're also one step down the road of refactoring the static data away, as Ilja suggests.
+Pie Number of slices to send: Send
 

Originally posted by Steve L. Williams:
According to everything I have read static final variables are constants. Perhaps I misread I got severely annoyed when he tried to make his point by self-referencing.

I looked at his approach, but the variables values are not known at compile time, is this still going to work?

[ May 20, 2006: Message edited by: Steve L. Williams ]



Static "final variables" are not constants - you haven't read this: http://jqa.tmorris.net/GetQAndA.action?qids=13&showAnswers=true

Do I really need to provide a reference to point out why "final variable" is oxymoronic? Even so, I'd use an authoritative linguist (such thing?) if I were to do just that. I would not use Head First as any kind of authority, since most of the contentious (read: not well known) issues are portrayed in a false or overly-simplistic manner in that book - which leads to these unfortunate circumstances where an innocent person has been misled.

I used to work on implementing the JLS/APIS - I assure you there is much more to what goes on behind the scenes than what the public eye sees.
+Pie Number of slices to send: Send
 

Originally posted by Jim Yingst:
I agree with Ilja on this. But just to undermine his point , I offer one other way to fulfil the original goal of initializing a static final:

This is very much like using a static block.



I'm not sure that a specific point is clear - this code will actually compile to using a static initializer block, since the field is not a constant (otherwise, it is compiled to class' constant_pool). Choosing one over the other in these circumstances (non-constant) applies only to the source. The same can be said for non-static final fields and instance initializers.
+Pie Number of slices to send: Send
Thank you Jim, Jaime, and Ilja for your help. I will look at other options. I don't think that what I am doing will tightly couple my code. Those variables are only used in cases where it really doesn't matter what they are, and changing it will require no additional code changes and little testing. Mainly they are used as codes to send to the client or to specify certain attributes.

For example, MAXSIZE sets how many commections to the server are allowed at one time. The server keeps track of how many connections and compares it to MAXSIZE and behaves accordingly. If MAXSIZE get changed, so what? The server won't really care or behave differently.

[Tony]: Static "final variables" are not constants - you haven't read this: http://jqa.tmorris.net/GetQAndA.action?qids=13&showAnswers=true

Do I really need to provide a reference to point out why "final variable" is oxymoronic? Even so, I'd use an authoritative linguist (such thing?) if I were to do just that. I would not use Head First as any kind of authority, since most of the contentious (read: not well known) issues are portrayed in a false or overly-simplistic manner in that book - which leads to these unfortunate circumstances where an innocent person has been misled.


Like I said it is a oxymoron, but the meaning is still quite clear. static final int myval=5 is a constant. It completely adheres to the rigourous definition of constant. Let us say that you are correct, what possible bad thing can happen by acting like that variable is constant? Nothing.

Again, trying to prove a point by referencing yourself is very academically dishonest.

The world is flat and here is proof: www.mysite.com/theworldreallyisflat.html.

Who cares that it is completely opposite of conventional wisdom, I know better then anyone else.

Sorry I will take the word of Ms. Sierra and Mr. Bates over you.

[ changed code tag to boldface quote so the line isn't hideously overlong - Jim ]
[ May 21, 2006: Message edited by: Jim Yingst ]
+Pie Number of slices to send: Send
[Steve]: Again, trying to prove a point by referencing yourself is very academically dishonest.

Oh, come now. The point is that if you follow the link, you find additional discussion which supports his point. If you disagree with points in that discussion, feel free to point them out. If you find an error, Tony will fix it. Well, sometimes. But linking to one's own site is not inherently dishonest. Like many of us, Tony has found that many points in discussions here tend to recur frequently, and it's tiresome to write the same thing each time. One could cut and paste the same text as the last time, I suppose. But Tony's solution seems quite reasonable to me - link to his own Java FAQ. Why not? Tony in and of himself is not inherently authoritative, but many of the discussions in his FAQ will take pains to either reference the JLS, or provide code which you can use to see what your JDK actually does. How much more authoritative do you want it to be? Read what he has to say there, and evaluate for yourself whether or not it makes sense. It may, or it may not. But don't stop just because it's Tony's own site. He's not hiding the fact that he's referencing himself - it's just a convenience to avoid repeating himself.

[Steve]: Sorry I will take the word of Ms. Sierra and Mr. Bates over you.

Hurm. I know Kathy and Bert personally and like them a lot. Whereas Tony and I have a history that is... patchy at best. Plus, Kathy is like, incredibly hot. And Bert is very . However I think you should consider the possibility that books like Head First Java and the K&B SCJP book may present somewhat... simplified views of things. Whether this is good or bad is arguable. Simplicity is good for a beginner, while oversimplification is (by definition) bad. Where exactly the line lies... is fodder for many more post between Tony and myself, and others, potentially. And in some cases they (K&B) may be flat-out wrong. They aren't gods. Neither is Tony, neither am I, neither are the authors of the JLS. Frankly all of us have committed errors st least occasionally in the past, and we will doubtless continue to do so in the future. You need to approach any source with a certain amount of skepticism. Learn from them when they're right, ignore them when they're wrong, and pay attention to their overall error rates so you can use this in evaluating their reliability in the future.

I suppose I should note that at the moment I have no idea what particular part of HFJ you are referencing here. Care to provide a quote? K&B are more than willing to make corrections if they're necessary.

Also I note that I myself have also provided direct links to relevant sections of the JLS which support the idea that your MAXSIZE variable (excuse me, I meant your final thing-which-has-no-other-acceptable-name-under-the-JLS thingie) is not a constant. Are you planning on looking into those references? I know Tony can rub some people the wrong way (trust me, I know) but that doesn't make him wrong.
+Pie Number of slices to send: Send
 


I know Tony can rub some people the wrong way (trust me, I know) but that doesn't make him wrong.


Any Australians who watched A Current Affair on Friday (19/05) night will now know that too I just got back from magistrates court - adjourned
+Pie Number of slices to send: Send
Tony - well, damn. Now I need details, dammit! If a more specific link becomes available, please let us know. From my limited perusings, the Australian ACA site seems somewhat crapulescent - I can't find any clues to what you might be talking about. Usually that's my cue to simply ignore and move on. But for the moment, I'm curious.

[Tony]: I'm not sure that a specific point is clear - this code will actually compile to using a static initializer block

Hmm, isn't the notion of a "static initializer block" inherently specific to the source code? After compilation it becomes something that goes (directly or indirectly) into the <clinit> method. Whether it originally came from a static initializer block is immaterial at this point, isn't it? Otherwise though, I agree with Tony. If Steve wants to initialize MAXSIZE from a file, that's cool. But it will never, ever, be a "constant" (or more specifically, a compile-time constant expression) as the JLS defines it. Does this distinction matter? Maybe not, at this moment. But understanding other parts of the JLS is contingent on understanding the JLS definition of "constant".
+Pie Number of slices to send: Send
I'll leak bits and pieces Here is the allegation by the Queensland Police Service: http://www.austlii.edu.au/au/legis/qld/consol_act/ppara2000365/s444.html Makes me look real bad without more detail, but I'll drop the bombshell another time I'm not that fond of any current affairs shows - or even tv for that matter - but ACA is the second biggest in the country (Today Tonight being the biggest) in terms of number of viewers.

Regarding initializers/clinit, yes initializers as we know them apply to source code and refer to the clinit instruction when compiled. The point was that an inline non-constant (but potentially final) declaration is compiled to a <clinit>.
+Pie Number of slices to send: Send
We've got a rule here which is printed large and put on the wall: "The only good global is a global you're removing".
Live by that.
+Pie Number of slices to send: Send
 

Originally posted by Steve L. Williams:
For example, MAXSIZE sets how many commections to the server are allowed at one time. The server keeps track of how many connections and compares it to MAXSIZE and behaves accordingly. If MAXSIZE get changed, so what? The server won't really care or behave differently.



The point is that it works fine as long as you only have one server, and exactly one way to determine the MAXSIZE.

Once you want to have more than one server at the same time (in the same VM) with different MAXSIZEs, or want more flexibility in determining MAXSIZE, you will have to change every line of code that directly references the global. For a trivial example, imagine that MAXSIZE normally gets read from a configuration file, but for unit testing the server, you don't want to use a configuration file but hardcode the value in the test.

In this specific example, the pain might not be too big, because the global isn't referenced from many places. Still, I'm very hesitant to using globals.
+Pie Number of slices to send: Send
 

Originally posted by Jeroen T Wenting:
We've got a rule here which is printed large and put on the wall: "The only good global is a global you're removing".
Live by that.



We probably shouldn't digress on this thread, but I'd be curious to hear your definition of "global". I contest that so such thing can exist.
+Pie Number of slices to send: Send
In Java no, but in C, yes it can. So there is such thing as global variables. Something to be avoided but they still have their place, as does the much hated(and rightfully so)goto statement. It all depends on the situation.

I suppose I should note that at the moment I have no idea what particular part of HFJ you are referencing here. Care to provide a quote? K&B are more than willing to make corrections if they're necessary.



page 282 at the top is large black letters: "Static final variables are constants", and goes on with an example of PI from the Math class. Guess what, it can be called all over my program if I wish it! It must be bad programming then. It also calls them that elsewhere.

By the way, what possible relevance is your opinion that Kathy is 'hot'. I hope she smacked you for being sexist.

[ changed code tag to quote tag because... well... it's a quote. QED - Jim ]
[ May 25, 2006: Message edited by: Jim Yingst ]
+Pie Number of slices to send: Send
[Steve]: By the way, what possible relevance is your opinion that Kathy is 'hot'.

None, other than to butter Kathy (and Bert) up in case they read what I said. Your concern about it is noted, but quite unnecessary.

Your "guess what" comment seems to a non sequitor to anything I said (despite being a reply to my quote), so I guess I'll move on now.
+Pie Number of slices to send: Send
 

Originally posted by Steve L. Williams:
In Java no, but in C, yes it can. So there is such thing as global variables. Something to be avoided but they still have their place, as does the much hated(and rightfully so)goto statement. It all depends on the situation.



page 282 at the top is large black letters: "Static final variables are constants", and goes on with an example of PI from the Math class. Guess what, it can be called all over my program if I wish it! It must be bad programming then. It also calls them that elsewhere.

By the way, what possible relevance is your opinion that Kathy is 'hot'. I hope she smacked you for being sexist.

[ changed code tag to quote tag because... well... it's a quote. QED - Jim ]

[ May 25, 2006: Message edited by: Jim Yingst ]



Despite Kathy and Bert being very intelligent people with a great book, if that is literally what the book says then it is simply wrong. A constant variable must also be a primitive type or of type String and must be initialized with a constant expression. Since you've shown remarkable resistance to truth here it is right out of the JLS:

4.12.4 final Variables
A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned (�16) immediately prior to the assignment.

A blank final is a final variable whose declaration lacks an initializer.

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object. This applies also to arrays, because arrays are objects; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.

Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

In the example:

class Point {
int x, y;
int useCount;
Point(int x, int y) { this.x = x; this.y = y; }
final static Point origin = new Point(0, 0);
}

the class Point declares a final class variable origin. The origin variable holds a reference to an object that is an instance of class Point whose coordinates are (0, 0). The value of the variable Point.origin can never change, so it always refers to the same Point object, the one created by its initializer. However, an operation on this Point object might change its state-for example, modifying its useCount or even, misleadingly, its x or y coordinate.

We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (�15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (�12.4.1), binary compatibility (�13.1, �13.4.9) and definite assignment (�16).

 
+Pie Number of slices to send: Send
Quote:
A blank final is a final variable whose declaration lacks an initializer.

I am getting confused from the above quote . I always thought final variable
always have to have an initializer otherwise there will be a compile time error. so what does blank final means in Java 1.4 ???
[ May 25, 2006: Message edited by: Chris Wox ]
+Pie Number of slices to send: Send
 

Originally posted by Steve L. Williams:
Actually I am using them as program wide variables, not just in the class. Is this the way to go about it?

I guess it doesn't have to be final since the variables are unique to this program. Are there security issues with having these variables public and not final? This is going to be a server app.



Quote :
Secure Code Guidelines
Refrain from using public variables. Instead, let the interface to your variables be through accessor methods. In this way it is possible to add centralized security checks, if required.


Static fields

* Refrain from using non-final public static variables


To the extent possible, refrain from using non-final public static variables because there is no way to check whether the code that changes such variables has appropriate permissions.

* In general, be careful with any mutable static states that can cause unintended interactions between supposedly independent subsystems
[ May 25, 2006: Message edited by: Chris Wox ]
+Pie Number of slices to send: Send


That's a blank final, it's declaration lacks an intializer. In the case of a field it still has to be intialized, it's just done elsewhere. In the case of a local final variable it doesn't necessarily have to be initialized at all if it's never used.
+Pie Number of slices to send: Send
Can I declare static final variable without initializing it in Java 1.4 ?

private static final int i;
+Pie Number of slices to send: Send
Yes.
+Pie Number of slices to send: Send
 

Originally posted by Tony Morris:


We probably shouldn't digress on this thread, but I'd be curious to hear your definition of "global". I contest that so such thing can exist.



In Java, not outside classloader scope. In other languages, they're all over the place.
A static member in Java is essentially global to the classloader, and as most applications run inside a single classloader they're scoped to the entire application and therefore essentially global.
+Pie Number of slices to send: Send
 

Originally posted by Jeroen T Wenting:


In Java, not outside classloader scope. In other languages, they're all over the place.
A static member in Java is essentially global to the classloader, and as most applications run inside a single classloader they're scoped to the entire application and therefore essentially global.



I'll restrict the argument to Java. Since we have now moved to "essentially global", I also contest the legitimacy of such a thing. If I create two class loaders, is the "essentially global" still essentially global? ... or is it only essentially global when there is only ever one class loader?
+Pie Number of slices to send: Send
 

Originally posted by Ken Blair:
Yes.




I checked this we are only allowed to do below for local variable and for
field variables we must initialized the value meaning blank final is only applicable for local variables ... java v 1.4

final int x ;
[ May 26, 2006: Message edited by: Chris Wox ]
+Pie Number of slices to send: Send
Global to a classloader is bad enough. When people then also expect (as many do) it to be global across classloaders when it isn't it goes downhill from there and you (as the initial programmer) have something you think is global but isn't and it's for the maintenance programmer to figure out what the problem is and fix it which may well turn out to be a rather expensive rewrite.

Almost as bad as the scenario where you have a global that you think isn't and gets changed somewhere outside your control...
+Pie Number of slices to send: Send
 

Originally posted by Chris Wox:



I checked this we are only allowed to do below for local variable and for
field variables we must initialized the value meaning blank final is only applicable for local variables ... java v 1.4

final int x ;

[ May 26, 2006: Message edited by: Chris Wox ]



You seem to be missing the distinction between a final being intialized somewhere and it being initialized with a variable initializer in it's declaration. Of course all final fields must be initialized but they don't have to be initialized in their declaration. When the initialization occurs elsewhere it is a blank final.
+Pie Number of slices to send: Send
 

Originally posted by Jeroen T Wenting:
Global to a classloader is bad enough. When people then also expect (as many do) it to be global across classloaders when it isn't it goes downhill from there and you (as the initial programmer) have something you think is global but isn't and it's for the maintenance programmer to figure out what the problem is and fix it which may well turn out to be a rather expensive rewrite.

Almost as bad as the scenario where you have a global that you think isn't and gets changed somewhere outside your control...



We have now shifted to "global to a class loader". This marks my original point - a "global" does not exist without provided context (for your case a class loader).

A local declaration is a "global".

A field declaration is global.

An object instance is global. A class is global. A class loader is global. A JVM is global. All JVMs in the universe are global. When does the universe end? I certainly don't know. Either everything within it is a "global" or nothing is. Or, a "global" exists within a given context/scope with the obvious and erroneous connotations implied by the term "global".

One could point to the established point of view - resulting from the writings of the like of GoF and subsequently Sun Microsystems - as some form of authority. These writings are outdated, and even if they weren't, they are incorrect and misleading (we'll cover that another day). There are some people who faith in a bible, some who put faith in GoF, some who put faith in some other demigod, but I prefer to question all forms of claimed authority in the pursuit of knowledge.
+Pie Number of slices to send: Send
 

Originally posted by Ken Blair:


You seem to be missing the distinction between a final being intialized somewhere and it being initialized with a variable initializer in it's declaration. Of course all final fields must be initialized but they don't have to be initialized in their declaration. When the initialization occurs elsewhere it is a blank final.



I think I am not missing anything and I understand this concept but I cant agree with what you are saying above at least with Java 1.4 and above.

When I am trying to declare a final field without being initialized it is giving me compiler error asking for the initial value and no such problem in the local variables !

I saw the qs on the rule roundup game on this website also telling that latest compiler are forcing this restriction !
[ May 26, 2006: Message edited by: Chris Wox ]
+Pie Number of slices to send: Send
try twisting words Tony, you won't get smart people to admit that everything is global or that having everything accessible to all the world to do with as they please is a smart thing to do.
+Pie Number of slices to send: Send
 

Originally posted by Jeroen T Wenting:
try twisting words Tony, you won't get smart people to admit that everything is global or that having everything accessible to all the world to do with as they please is a smart thing to do.



I have applied the method of contradiction to derive a conclusion. I believe you misunderstood the point at hand.
+Pie Number of slices to send: Send
[Chris]: When I am trying to declare a final field without being initialized it is giving me compiler error asking for the initial value and no such problem in the local variables !

Generally the rules are set up to try to prevent you from using a final variable before it's been assigned - whether it's a static field, member field, or local variable. But there are still some loopholes in which it doesn't work out.

Here, final variable bar is not initialized, but it is definitely assigned by the constructor. And you can observe it actually change value despite being final:

Conversely, here is an example of a local variable in which the compiler prevents you from accessing the variable before it's been assigned:

[ May 27, 2006: Message edited by: Jim Yingst ]
+Pie Number of slices to send: Send
To point out how definite assignment applies to final fields and to build on Jim's example, here is another example where foo is definitely assigned:

...while this code - almost exactly the same - shows where foo is not definitely assigned:

In the former case, foo is not a constant, while the latter case, the definition of foo is indeterminate (since it will not compile).
+Pie Number of slices to send: Send
Tony, thanks a lot for the explanation , your example above is very important to understand the compiler behaviour
[ May 28, 2006: Message edited by: Chris Wox ]
A magnificient life is loaded with tough challenges. En garde tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 1865 times.
Similar Threads
Builder to read xml? is this the right way?
Core Java 2 Ex. 5-3
what makes a compile time constant?
Access Program Names from Windows Registry
How to read mainframe file (in .txt) and assign values to variables.
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
Passing a Variable value from one Method to another Method
Changing file
What happens to the static variable here ? Threads !
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 17:58:39.