• 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

forward referencing

 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
can anybody explain this.
public class AQuestion
{
private int i = j;
private int j = 10;
public static void main(String args[])
{
System.out.println((new AQuestion()).i);
}
}
Answers
Compiler error complaining about access restriction of private variables of AQuestion.
Compiler error complaining about forward referencing.
No error - The output is 0;
No error - The output is 10;
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The comiler complains about a Forward Referencing error and not about the access protection.
This is because JAVAC is a single pass compiler. The moment it comes across the statement int i=j; it flags an compile time error. so further checks on the statement are not done till the present error is removed.
Now if we remove the forward referencing :
public class AQuestion
{
private int j = 10; // no forward referencing
private int i = j;
public static void main(String args[])
{
System.out.println((new AQuestion()).i);
}
}
>>> The program compiles and runs : output is 10
private access modifier restricts access from other classes but we are using the variable i in the same class AQuestion there is now no compile time error.

 
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
what is the difference between my question above and the question below and why do they give different results.

public class AQuestion
{
private int i = giveMeJ();
private int j = 10;
private int giveMeJ()
{
return j;
}
public static void main(String args[])
{
System.out.println((new AQuestion()).i);
}
}
Answers

1. Compiler error complaining about access restriction of private variables of AQuestion.
2. Compiler error complaining about forward referencing.
3. No Compilation error - The output is 0;
4. No Compilation error - The output is 10;
the answer is 3 for above

[This message has been edited by rahul_mkar (edited May 12, 2000).]
[This message has been edited by rahul_mkar (edited May 13, 2000).]
 
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
Rahul,
IMO when you are declaring int i in the second program, you're pointing this to get the value from the result of a method which is OK.
During compile time, it just checks whether that method with appropriate signature is coded or not (Anywhere in the program, not necessarily before the first reference). Since it's coded somewhere(giveMeJ()), it compiles fine.
During runtime, it tries to execute the method and since it could find one to execute, it runs fine and gets the value.
HTH
Prabhu.
 
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
rahul_mkar,
Prabhu is correct. To add on to this, at runtime when an object of this class is created, since instance vars are initialized in the SAME SEQUENCE as they are written in the source file, the var i is initialized first, which in turn calls the giveMeJ() fn which in turn returns the instance var j. The important point to note here is when giveMeJ() is called, the instance var j is NOT YET initialized and so all the instance vars have their default values, the default val for 'int' type which is 0 (zero) is returned.
If the ORDER of initialization WOULD have been changed like the foll.

private int j = 10;
private int i = giveMeJ();

then the var i will have value 10.
regds
maha anna
 
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
hi,
i would like to know
1) what is the sequence of variable creation, is it static variables first and then instance variables or vice versa
for example
class x{
static int i=5;
int z=3;
}
would i be created first and then z
or
z first and then i or
both at almost the same time;

2)if all variables created first and then initialized as the written sequence then in my first example
"private int i = j; private int j = 10; comiler complains about a Forward Referencing error"
in the above case variables i and j should have been initialized to 0 and then when it comes to the first statement ie "private int i=j" then i should have been assigned 0 and then in the next statement it should have been assigned 10. However this does not happen.

please clarify especially on how the two questions give different results.
 
maha anna
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
rahul_mkar,
for your first request
-----------------------------
static init is done first (when the class is loaded into memory itself), then comes the instance init (done when an object is created from this class).
For example when you access a class's static method, the class is loaded into memory and so ONLY the static floatin blocks, static (class) vars are initialized an written in the same order in the source file. NO instance init done.
At the same time when you do new ThisClass() then if the class is not already in memory, then it is loaded and both static and instance inits are done. Otherwise if it was already loaded before then only the instance init are done and the correcponding constructor is called.
So in your code the static var i is initilized first and then z is initialized. I wrote this sample prog. for you. Play with this. It WILL DEFINITELY make you think./confuse/....clear at the end
************************************************************
output

stat block test1 called
------0
stat block test2 called
------10
stat block test3 called
instance block test1 called
Constructor test1() called
instance block test2 called
Constructor test2() called
instance block test3 called
Constructor test3() called

<pre>
class test1 {
static int stat11 =10;
static {
System.out.println("stat block test1 called");
}
int inst11 =20;
{
System.out.println("instance block test1 called");
}
test1() {
System.out.println("Constructor test1() called");
}
}
class test2 extends test1 {
static int stat21 =10;
static {
System.out.println("------"+test3.stat31);
System.out.println("stat block test2 called");
}
int inst21 =20;
{
System.out.println("instance block test2 called");
}
test2() {
System.out.println("Constructor test2() called");
}
public static void main(String[] args) {
new test2();
}
}
class test3 extends test2 {
static int stat31 =10;
static {
System.out.println("------"+test3.stat31);
System.out.println("stat block test3 called");
}
int inst31 =30;
{
System.out.println("instance block test3 called");
}
test3() {
System.out.println("Constructor test3() called");
}
public static void main(String[] args) {
new test3();
}
}

</pre>
*********************************************************
ORDER OF EXECUTION
1. - static initialization for test1 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)
2. - static initialization for test2 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)
3. - static initialization for test3 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)

4. - instance initialization for test1 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
5. - Constructor test1() called

6. - instance initialization for test2 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
7. - Constructor test2() called

8. - instance initialization for test3 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
9. - Constructor test3() called
*********************************************************
for your 2nd request
--------------------------
At compile time you can't refer to a var as such if it not known before this referencing. THis is the rule. Because the var is not yet known. But when you call a fn what the compiler actually it basically creates code to which implementaion of the fn to execute like that. At run time when you call a method, and if it refers to a class/instance var, if it is not yet initialized , the default values are taken for granted. The important point to note here is eventhough the class/instance var are given default valuse you can't forward reference through the ref as such. Because the scope of a var and a method is differnet. A var's scope is at the place where it is declared and below the declaration point. But a method's scope is anywhere in the containing class. THis is the difference And also this is the reason why your programs behaves differently. Eventhough the link which I given below doesn't explicity elaborate this, we have link what is said in the 'scope' section and this context and come to a conclusion/reason.
regds
maha anna
From JLS
<pre>
The static initializers and class variable initializers are executed in textual order and may not
refer to class variables declared in the class whose declarations appear textually after the use,
even though these class variables are in scope. This restriction is designed to catch, at
compile time, circular or otherwise malformed initializations. Thus, both:
class Z {
static int i = j + 2;
static int j = 4;
}
and:
class Z {
static { i = j + 2; }
static int i, j;
static { j = 4; }
}
result in compile-time errors.
Accesses to class variables by methods are not checked in this way
class Z {
static int peek() { return j; }
static int i = peek();
static int j = 1;
}
class Test {
public static void main(String[] args) {
System.out.println(Z.i);
}
}
produces the output:
0
</pre>
Please refer to JLS especially this section
regds
maha anna

[This message has been edited by maha anna (edited May 14, 2000).]
 
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

Originally posted by rahul_mkar:
hi,
i would like to know
1) what is the sequence of variable creation, is it static variables first and then instance variables or vice versa
for example
class x{
static int i=5;
int z=3;
}
would i be created first and then z
or
z first and then i or
both at almost the same time;
class MBT{
MBT(int i){
System.out.println(i);
}
}
public class Stat {
static MBT m1=new MBT(1);
MBT m2=new MBT(2);
static MBT m3=new MBT(3);
public static void main(String[] s){
Stat st=new Stat();
}
}
Try out this program you have your answer.

2)if all variables created first and then initialized as the written sequence then in my first example
"private int i = j; private int j = 10; comiler complains about a Forward Referencing error"
in the above case variables i and j should have been initialized to 0 and then when it comes to the first statement ie "private int i=j" then i should have been assigned 0 and then in the next statement it should have been assigned 10. However this does not happen.

please clarify especially on how the two questions give different results.


reply
    Bookmark Topic Watch Topic
  • New Topic