Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are java global variables guaranteed to initialize first?

Not actually global variables, but just variables that are class-wide.

For example, I have this initialization:

MyObj obj = new MyObj();

And then I have this method:

public void Foo(){
    obj.doSomething;
}

Let's say that I'm not able to use a constructor(this is pertaining to android). Will the variable be guaranteed to always be initialized before any methods in the class is called?

like image 367
ryye Avatar asked Sep 14 '15 07:09

ryye


3 Answers

(To be clear: 1) Java doesn't have global variables. 2) Java has class (i.e. static) fields and instance fields, as well as local variables. 3) The example appears to show an instance field, so I am assuming that is what you are asking about.)

Are java global variables guaranteed to initialize first?

Yes. Except in pathological cases that I will explain below.

When an object is created, the following things are done in the following order:

  1. The object is allocated on the heap with the correct object type, and all instance fields are "default initialized" to zero, false or null.

  2. The expressions in the super(...) or this(...) are evaluated and the constructor for the next class up the chain is called. (This recurses up the chain constructor, so that the Object constructor gets executed first.)

  3. The instance variable initializers and any instance initializer blocks are executed in order.

  4. The body of the constructor is executed.

  5. The constructor returns.

All of this happens when you execute new SomeClass(...).

So, in your example (as written), you can sure that the instance variable obj will be initialized before your method is called.


Now for the pathological cases. Consider this:

public class Foo {

    private int a = someMethod();
    private int b = 42;

    public Foo() {
    }
    
    private int someMethod() {
        return this.b;
    }
}

In this case, the initializer for a will call someMethod before b has been initialized, and hence someMethod will return the default initial value of b ... zero. You could also "implement" the pathological example using an instance initialize block. However, if you called someMethod within the Foo constructor, you can be sure that the instance variable's initializer will have been executed.

Indeed there are other pathological cases to consider. If the implementation of someMethod in the above were to call a method in another class, passing this as an argument, then the other class could call methods on the partially initialized Foo instance. (This is called unsafe publication. It is particularly insidious if the partially initialized instance can be accessed by another thread, because that invalidates various Java memory model guarantees.)

like image 83
Stephen C Avatar answered Nov 03 '22 00:11

Stephen C


Will the variable be guaranteed to always be initialized before any methods in the class is called?

Yes. You are correct. It's already initialized since it's declared even on top of constructor and ready for the use later.

And it's up to you, where you are going to use that instance member, weather in constructor or in methods later, but it's guaranteed to initialize before the constructor called.

like image 33
Suresh Atta Avatar answered Nov 03 '22 00:11

Suresh Atta


First of all, it's not a global variable. It's an instance variable. It is guaranteed to be initialized before the constructor is called, so it is guaranteed to be initialized when Foo is called.

like image 32
Eran Avatar answered Nov 03 '22 00:11

Eran