Question

I'm running into a problem when I compile my code. When I compile my code foo2.var returns null in class foo and I can't seem to figure out why. Is there something wrong in how I'm doing the static initialization in the foo2 class to cause foo2.var to be null in the foo class?

Any help is appreciated.

public class foo extends bar {
  public final static String blah = foo2.var;
  ...
}

public abstract class bar {
  ...
}

public class foo2 extends bar {
  public final static String var;

  static {
    var = "newstring";
  }
  ...
}

Null pointer error on the foo2.var line in this example.

Was it helpful?

Solution 2

Accessing a static field (whose value is not a compile-time-constant expression) will trigger initialization of the class declaring that field, during which which the static initializers are executed. However, initialization is only guaranteed to have completed by the time the field is read if there is no cyclic dependency among initializers.

For instance, if you run the program

class Bar {
    static final long bar;

    static {
        System.out.println("Assigning bar");
        bar = Foo.foo;
    }
}
class Foo extends Bar {
    static final long foo;

    static {
        System.out.println("Assigning foo");
        foo = 1;
    }
}

public class Test {
    public static void main(String[] args) {
        new Foo();
        System.out.println(Bar.bar);
    }
}

you get the following output:

Assigning bar
Assigning foo
0
1

because to create a new instance of Foo, Foo.class is initialized, which first initializes its super class Bar.class, which reads the field of Foo.class, but Foo.class is already being initialized. The Java Language Specification mandates in section 12.4.2, step 3, that such a recursive initialization completes immediately, i.e. the caller will see the class in a partially initialized state. That is, Foo.foo is unassigned at the time it is read, and therefore still contains the default value of 0. That value is assigned to Bar.bar, completing initialization of Bar.class. Then, initialization of Foo.class is resumed by running the initializer, which sets Foo.foo to 1.

Practically speaking, you might wish to review the dependencies of your classes and structure your program such that there are no cyclic dependencies among initializers.

OTHER TIPS

You have not specified a type for var try public final static String VAR;

and then why not just

public class foo2 extends bar {
  public final static String var = "newstring";

var doesn't have a type. Also constants in Java are uppercase by convention. Make it:

public class Foo2 {
  public final static String VAR;

  static {
    VAR = "newstring";
  }
  ...
}

You are missing a type for var, change that line to the following:

public final static String VAR;

Specify var type.

Also, by coding convention class names should be written in CamelCase and constants, UNDERSCORED_CAPS

public class Foo2 {
   public final static VAR = "newstring"; // why not?
...
}

Also, you may shadow foo2 class by some variable. Check your imports. Because class static field reference cannot produce NPE!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top