• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

unable to understand legal and illegal forward reference

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,
I understand that the following is an example of valid reference in java. I also understand that at class creation, first i and j are initialized to 0. j is then re-initialized to 5, as a result of which i's value is 0 and j's is 5 inside main.


But why is the same not true for the following ? Why is it that i and j are not initialized to the default value of 0 in this case and gives an illegal forward reference?


I would like some clarification on why the first is legal reference and the second illegal reference.

Thank you.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Iam Tubby wrote:I would like some clarification on why the first is legal reference and the second illegal reference.


You know what? I don't know; but I suspect it goes something like this:

The "first pass" creates the space for the two variables and establishes their names.
The second pass establishes
1. The method, which can now access j (which at this point has a value of 0).
2. Sets i to the result of test();
3. Sets j to 5.

Not exactly sure - I suspect you could test the mechanics a bit further by moving the method declaration between i and j.

I hate to say, but it's something you'll probably never have to deal with (and certainly not if you write your classes properly). So I'd say it comes under the heading of DontSweatIt.

Is there any particular reason you think it might be important?

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



What you are doing here is forward reference i.e using an identifier before its declaration. Based on situation it will either result in an error, warning or return with default values(as in this code).
It is logically wrong and hence the value being returned by test() is default value.



This is an illegal forward reference. [error]


This is the correct way to do it i.e follow procedure as compiler would. However still a warning would be generated as "the value of a static(non-final) variable will depend on the order of initialization statements".

lets see a sample code..


Suppose another class member is using and altering the value of j before i copies it it'd result in logical errors in the program. Hence it's not advised to use static non-final for initialization purposes.


 
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The reason that the following is illegal is because of the order of initialization from the compiler



Static and instance variables within the declaration of a class are initialized to their default values in their order of declaration ... In the above code i is trying to copy the value from j which has not yet been initialized since it was declared after i
 
Aftab Hassan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:
The "first pass" creates the space for the two variables and establishes their names.
The second pass establishes
1. The method, which can now access j (which at this point has a value of 0).
2. Sets i to the result of test();
3. Sets j to 5.


Winston, thank you for the reply and sorry for my late response.
That makes sense, but why isn't the explanation regarding first and second pass applicable to static int i = j;static int j=5; ?
I would have hoped for something like,
1. The "first pass" creates the space for the two variables and establishes their name, and sets i and j to the default value of 0
2. Sets j to the value of 5
Why does the same concept behave differently depending on whether the value is coming from a variable or a function ?


I hate to say, but it's something you'll probably never have to deal with (and certainly not if you write your classes properly). So I'd say it comes under the heading of DontSweatIt.
Is there any particular reason you think it might be important?


Thanks for pointing out. At this point, I'm not really sure of what's important and what's not. I'll give it some more thought and keep looking out for responses. If I still find it confusing it, I'll call it off.

Thanks once again
 
Aftab Hassan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Shubham Semwal wrote:



What you are doing here is forward reference i.e using an identifier before its declaration. Based on situation it will either result in an error, warning or return with default values(as in this code).
It is logically wrong and hence the value being returned by test() is default value.


Thanks for the reply Shubham. If it is logically wrong, then why does Java support this kinda initialization ?
Wouldn't it have been much better if variable initialization was achieved only if variables appeared in the correct textual order, as in, no legal forward referencing at all.
 
Aftab Hassan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rico Felix wrote:The reason that the following is illegal is because of the order of initialization from the compiler



Static and instance variables within the declaration of a class are initialized to their default values in their order of declaration ... In the above code i is trying to copy the value from j which has not yet been initialized since it was declared after i


Thanks for the reply Rico. I understand, but why is initialization allowed from a method, even if variables are not initialized in the order of declaration. As in, how are we able to access j before i in spite of j being initialized after i.(refer snippet below)
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Iam Tubby wrote:

Rico Felix wrote:The reason that the following is illegal is because of the order of initialization from the compiler



Static and instance variables within the declaration of a class are initialized to their default values in their order of declaration ... In the above code i is trying to copy the value from j which has not yet been initialized since it was declared after i


Thanks for the reply Rico. I understand, but why is initialization allowed from a method, even if variables are not initialized in the order of declaration. As in, how are we able to access j before i in spite of j being initialized after i.(refer snippet below)



As I have said before, the compiler ensures that each class member gets a default value in their order of declaration. The variable declarations may be scattered throughout and in between method definitions, but the variables are initialized before any methods can be called.

Therefore if we have the following:



The compiler takes the following steps:
1. i will be initialized to its default value of 0 then reassigned the value 7
2. j will be initialized to its default value of 0 then reassigned the value 10

So to completely answer your question for the following code snippet:



The compiler takes the following steps:

1. i will be initialized to its default value of 0
2. j will be initialized to its default value of 0
3. i will be reassigned the value of 0 from the internal method call.
4. j will be reassigned the value of 5.

Therefore the following will be illegal:



For the reason that j is declared after i and is not even initialized to its default value.

i will be initialized to 0, then the compiler will look for the value for j to reassign i to the value j has and expects it to be found before i.

The method won't be called until the variables have been properly initialized.

I hope I have explained it clearly.
 
Shubham Semwal
Ranch Hand
Posts: 176
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Thanks for the reply Shubham. If it is logically wrong, then why does Java support this kinda initialization ?
Wouldn't it have been much better if variable initialization was achieved only if variables appeared in the correct textual order, as in, no legal forward referencing at all.



compiler is a set of codes .. it can't check logic.
There is no way for the program to make an optimized variable textual order.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thinking in Java
 
Aftab Hassan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rico Felix wrote:
The variable declarations may be scattered throughout and in between method definitions, but the variables are initialized before any methods can be called.


I was only wanting to know how variables and methods are behaving differently when the logic is pretty much the same for the two classes I posted.
This cleared everything. Thanks a lot Rico Marking the thread as solved

Shubham Semwal wrote:
compiler is a set of codes .. it can't check logic.
There is no way for the program to make an optimized variable textual order.


Thanks Shubham
 
reply
    Bookmark Topic Watch Topic
  • New Topic