Java Legal Forward Referencing

Go To StackoverFlow.com

12

Is the following code the case of legal forward referencing? if yes why?

public class MyClass
{
  private static int x = getValue();
  private static int y = 5;
  private static int getValue()
  {
    return y;
  }
  public static void main(String[] args)
  {
    System.out.println(x);
  }
}
2012-04-05 20:55
by Vibhor


19

The above code you have is perfectly legal Java. In Java, static fields are initialized as follows: first, all fields are set to the default for their type (0, false, or null), and then initialized in the order in which they are declared. This means that the above code is guaranteed to do the following:

  1. Set x and y to zero, since that's the default value for ints.
  2. Initialize x by calling getValue(), which reads the value of y. Since y hasn't yet been initialized, it still has the value 0.
  3. Initialize y to 5.

This means that x will take the value 0 and y will take the value 5. This behavior is portable and guaranteed. You can see this here.

Hope this helps!

2012-04-05 20:58
by templatetypedef
What would be the case if those were not Static variables and method - Vibhor 2012-04-05 21:05
I believe that the behavior is the same - the initialization is first setting everything to the default value, then initializing each with the specified value, then calling the constructor - templatetypedef 2012-04-05 21:06
Which, btw, is one reason you should never call a non-final (or private) method from a constructor; it's too easy for someone to override that method and see a not-yet-constructed this, even to the point of seeing an uninitialized final field - yshavit 2012-04-05 21:26
Doesn't your answer go against the answer below where you get a forward reference error with private static int x=y; private static int y=5; - Neil Walker 2013-01-29 10:50
@user1186046- Java allows you to indirectly have one variable forward reference another, but doesn't let you directly have one variable forward-reference another. The OP's code doesn't directly set x equal to y, so there is no error. However, you are right that your version of the code will give a forward reference error - templatetypedef 2013-01-29 17:01


5

You can tell whether it's legal or not by the fact that it compiles; unlike some other languages, Java doesn't have the notion of "undefined behavior." What happens here is completely spelled out. It may be counterintuitive, but it's specifically legal: you can access a static variable before it's initialized from a method called while initializing another static variable. The superficially similar case of accessing y directly from x's initializer -- i.e.,

private static int x = y;
private static int y = 5;

is specifically disallowed. There's really no strong reason why -- it's just how it is.

2012-04-05 21:00
by Ernest Friedman-Hill
What if the variables are non static..is the behavior same in that case too - Vibhor 2012-04-05 21:09
Yes, it's effectively the same. The rules listed for statics are very slightly different because there are no actual "constructors" for a class, but objects are initialized in essentially the same way. For instance variables, initializers and instance blocks are prepended, in order of appearance, to each constructor. For statics, initializers and static blocks are compiled, in order, into a single method named <clinit>() - Ernest Friedman-Hill 2012-04-05 21:15
Having a program that can be tested with a compiler is a luxury when it comes to questions like this I'm afraid. This is taken from a mock exam for OCJP exam. I'm learning it now, and it's these stupid questions that are completely pointless that make a mockery of the intent for the exam - Neil Walker 2013-01-29 10:52
Ads