• 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
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

local variable assignment

 
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi ..

I couldnt understand the difference in these 2 codes---that how come the first doesnot raise any
compiler error but the second one does???
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
else {
k = 4;
System.out.println(k);
}
}
The above code is ok.
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
if (!flag) {
k = 4; // k is not "definitely unassigned" before here
System.out.println(k);
}
}
But i feel both are same as for compiler
both ensure the definite assignment of the
local var k.


swapna
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Swapna,
The reason the compiler is complaining is because you have declared k to be final. In the second code fragment, the compiler realizes that k may already have been assigned a value in the first "if" statement. *You* are smart enough to tell that only one of these if statements will be executed, but the compiler is not so smart. It only knows that if both the first and second "if" statements test true, then a final variable may have a value assigned to it twice. That's illegal.
Changing the second "if" statement to "else if" fixes the problem.
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by swapna g:
Hi ..

I couldnt understand the difference in these 2 codes---that how come the first doesnot raise any
compiler error but the second one does???
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
else {
k = 4;
System.out.println(k);
}
}
The above code is ok.
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
if (!flag) {
k = 4; // k is not "definitely unassigned" before here
System.out.println(k);
}
}
But i feel both are same as for compiler
both ensure the definite assignment of the
local var k.


swapna


Hi Swapna
Here is what I think is going on...
First the compiler knows that when if executes else does not execute and when if does not executes than else will execute. So in your first code no matter what k is only assigned only one time, now in your second code the compiler sees two if and there is a possiblity that bth can execute. Your compiler is not smart enough to know that you are basically simulating an else. So when it sees two ifs, it can execute bth of them and what we have learned about final variables is that it can be assigned a value only one time, if you try to reassign it throws a compiler error.
I hope this helps!!!
Amish
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by James Childers:
*You* are smart enough to tell that only one of these if statements will be executed, but the compiler is not so smart.[/QB]


James is exactly right. In the case of an if/else construct, the compiler realizes that execution flow can only go one way or the other. Therefore, you can assign k in both branches and the compiler won't complain because it knows that only one part of an if/else construct can ever be executed.
However, an if statement followed by another if statement isn't so clear cut for the compiler. As far as it can tell, both tests could be true and therefore both blocks could be executed. This is what is causing your compiler error.
In this case, you can see that the compiler looks at the flow constructs (if/else, if, etc.), but it doesn't look at the arguments to those constructs. That's why you're seeing the error.
Corey
 
Ranch Hand
Posts: 732
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
for the second block of code the compiler doesnt know if k has been intialzed or not.
think like this:
there MIGHT be some code between the two if statments that put stuff in the k variable.
the compiler doesnt know that k will defintly be empty (unintialised).
also the compiler doesnt know that maybe k wont be intialised at all!! if at first the boolean
flag is equal to true and then we change it to false before the next if - then k wont be initalised at all.
only at if else the compiler can be sure k will get one and only one value.
 
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by swapna g:
Hi ..

I couldnt understand the difference in these 2 codes---that how come the first doesnot raise any
compiler error but the second one does???
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
else {
k = 4;
System.out.println(k);
}
}
The above code is ok.
void unflow(boolean flag) {
final int k;
if (flag) {
k = 3;
System.out.println(k);
}
if (!flag) {
k = 4; // k is not "definitely unassigned" before here
System.out.println(k);
}
}
But i feel both are same as for compiler
both ensure the definite assignment of the
local var k.


swapna


I played with the code and seem to have figured out the answer.
The compiler checks that a variable is either initialized or that a path of initialization exists within the context of where the variable is declared (in this case, a local final variable).
The code that fails does so because the compiler detects 2 paths where variable 'k' can be initialized. The "if(flag)" and "if(!flag)" are both valid paths for initializing 'k'. The fact that only 'true' or 'false' will be passed is apparently not taken into consideration by the compiler.
To fix this I added a 'return' statement after either the "if(flag)" or "if(!flag)" and everything worked fine.
HTH.
CG
 
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Or you can declare flag as a final variable inside the method, so the compiler will be smart enough to noticed that the code is ok.

That can be a trap, so pay attention to that case...
[ January 30, 2002: Message edited by: Valentin Crettaz ]
 
swapna sivaraju
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank u everyone...i got it!
I strongly agree with corey ,roy and Amish abt the if/else construct..!!!
Actually the problem is not with the variable
being declared as final but because of
if/else construct..as i tried the code
even removing the final modifier and still the
same result i got!!!

 
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
swapna:
Are you sure about removing final still working?
I tried this code too, it works if I remove final modifier. final modifier sure plays a rule in this error, since you cannot assign twice to a
final variable, while you can change a non-final
variable's value more than once.
victor

Originally posted by swapna g:
Thank u everyone...i got it!
I strongly agree with corey ,roy and Amish abt the if/else construct..!!!
Actually the problem is not with the variable
being declared as final but because of
if/else construct..as i tried the code
even removing the final modifier and still the
same result i got!!!

 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

swapna:
Are you sure about removing final still working?
I tried this code too, it works if I remove final modifier. final modifier sure plays a rule in this error, since you cannot assign twice to a
final variable, while you can change a non-final
variable's value more than once.
victor


yes I agree with victor. It works after final is removed
 
Roy Ben Ami
Ranch Hand
Posts: 732
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if u take the System.out.println statement out of the if blocks ,it wont compile even without the final keyword like we said.

Originally posted by swapna g:

void unflow(boolean flag) {
int k;
if (flag) {
k = 3;
System.out.println(k);
}
if (!flag) {
k = 4; // k is not "definitely unassigned" before here

}
System.out.println(k); //wont compile!!!
}

 
swapna sivaraju
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OOps!!!sorry guys!!!
Last time i posted my reply wrongly.....yeah
when i remove the final modifier it works fine..
and if the println statement is given as Roy stated then the error pops up...
swapna
 
permaculture is giving a gift to your future self. After reading this tiny ad:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic