Win a copy of TDD for a Shopping Website LiveProject this week in the Testing forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

Damm Final Variable

 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi everybody,
I am sick of this final variable.
public class Test4
{
final static int i;

public Test4()
{
i =10;
//System.out.println(i);
}

static public void main(String arg[])
{
new Test4();
System.out.println(i);
}
}
I am absolutely bamboozed with the 1st Error, which is as under.
'Blank Final variable `i' may not have been initialised. It must be assigned a value in an initialiser or in every constructor'
Then there is a second error which is as under:
'can't assign a second value to a blank final variable'.
From going through the discussion in javacert.com, i had come to understand that in JDK 1.2 (or 2 whatever) we need not assign a value to the final variable and can do that in the constructor. What the hell is happening? Now my questions
1) Why is the compiler complaining when i do not initialise a final variable. I thought JDK 1.2 is better than JDK 1.1, where you had to mandatorily initialise a final variable.
2) When i initialise a final variable to 'final int i = 5' and try changing the same in the constructor, it again cries and says cannot assign a second value to a final variable.
Tony, Paul, Jim help me as i am already booked for 7th Feb for exams. Thanking you in advance.
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with you. However, I did one change from your code and it worked. I removed the static modifier. and it WORKED!!
But I don't know why prefixing the static gives a problem
prasad
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good point Venkat....u made me to study a lot. I have got some explanation for u.
static final variables are called primitive constants. They should be initialized with a compile-time constant expression.
And also these variables are "constants" that will never be observed to have their default initial values.
Look at this example code which I got from java language specification document. ( This gives clear picture of how these primitive constants work )
Flags.java program :
class Flags { final static boolean debug = true; }
Test.java program :
class Test {
public static void main(String[] args) {
if (Flags.debug)
System.out.println("debug is true");
}
}
When u compile and execute, it produces the output as:
debug is true
And also look into the bytecodes for Test class file.
class Test
{
Test()
{
// 0 0:aload_0
// 1 1:invokespecial #7 <Method void Object()>
// 2 4:return
}
public static void main(String args[])
{
System.out.println("debug is true");
// 0 0:getstatic #8 <Field PrintStream System.out>
// 1 3:ldc1 #1 <String "debug is true">
// 2 5:invokevirtual #9 <Method void PrintStream.println(String)>
// 3 8:return
}
}
Here can u observe: System.out.println statement does not have any if case ( I meant icmp opcode ). It means that 'debug' class variable is resolved at compile time.
Now if u change Flags class a bit like this :
class Flags { final static boolean debug = false; }
If Flags is recompiled but not Test, then running the new binary with the existing binary of Test produces the output:
debug is true

If u compile Test as well, see the bytecode of Test:
class Test
{
Test()
{
// 0 0:aload_0
// 1 1:invokespecial #6 <Method void Object()>
// 2 4:return
}
public static void main(String args[])
{
// 0 0:return
}
}
I needn't explain about this now....
To avoid this kind of side effects, u can use conditional compilation as well.
So, the theme is that static final class variables should be initialized at the time of declaration.
I am waiting for some comments on this.
 
Sheriff
Posts: 6920
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Remember that static variables are shared between all instances of the class, and may even be accessed without any instances being constructed at all. Consider this simple eaxmple:
<pre>class X
{
public static int i;
public X()
{
i = 4;
}
}
public class Y
{
public static void main(String[] args)
{
System.out.println(X.i);
}
}
</pre>
Note that class Y accesses X.i before any object of class X is created. This is always possible for statics, so a final static member variable must be initialized either directly static final int i = 4; or in a static initialiser block, static { i = 4; }, both of which are run at the time the class is loaded, and before any static variables can be accessed.
 
Desperado
Posts: 3226
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For that reason, the compiler error



"Blank final variable 'i' may not have been initialized. It must be assigned a value in an initializer, or in every constructor:"



referring to
<CODE>final static int i;</CODE>
is completely misleading.
What do they mean "in every constructor"? In fact, if you follow the advice, then you get TWO errors. The one above plus:
"Can't assign a second value to a blank final variable: i"
I wonder, has the error msg been changed in Java 2.1 (=JDK.1.3)...?
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You know Tony, in a few weeks we're goig to be plagued with newbies asking where they can get Java 2.1, and it's going to be all your fault.
As it happens though, Java 1.3 beta does indeed fix the misleading message. I just get 1 error: "cannot assign a value to final variable i" for the line "i = 10;".
Occasionally Sun does fix these things. It warms my heart.
 
Venkat01
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tony, Jim, Frank
Everyone has talked about everything roundabout the world, but the question remains "WHETHER WE CAN GIVE ANOTHER VALUE TO THE FINAL VARIABLE (NOT NECESSARILY A BLANK VARIABLE)IN THE CONSTRUCTOR"
For the time being let us forget about Java 1.2 or Java 1.3. By the way when is Java 1.4++ coming (it will be a infinity loop - i do not know how to put the smile here).

But i definately remember seeing in javacert discussions that you can reassign a different value to the final variable in the Contructor (which was not possible in Java 1.1).
 
Tony Alicea
Desperado
Posts: 3226
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"But i definitely remember seeing in javacert discussions that you can reassign a different value to the final variable in the Contructor (which was not possible in Java 1.1)."


If it's not a static variable AND if it's not initialized when declared:
NOT OK:
<PRE>
public class Test {
 
final int i=0;
 
Test() {
i = 0;
}
 
}
</PRE>
YES OK:
<PRE>
public class Test {
 
final int i;
 
Test() {
 
i = 0;
}
}
</PRE>
 
Ranch Hand
Posts: 117
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I thought the entire idea of having a blank final variable is to have a constant within an instance. Without them, it becomes functionally same as static finals, right? (because each instance is going have the same value)
 
Self destruct mode activated. Instructions for deactivation encoded in this tiny ad.
Free, earth friendly heat - from the CodeRanch trailboss
https://www.kickstarter.com/projects/paulwheaton/free-heat
reply
    Bookmark Topic Watch Topic
  • New Topic