Java – problems in instance variable initialization

Here are some sample code,

class Base
{
  private int val;

  Base() {
  val = lookup();
  }

  public int lookup() {
    //Perform some lookup
  // int num = someLookup();
  return 5;
  }

  public int value() {
  return val;
  }
}

class Derived extends Base
{
  private int num = 10;

  public int lookup() {
  return num;
  }
}
class Test
{
  public static void main(String args[]) {

  Derived d = new Derived();
  System.out.println("d.value() returns " + d.value());

  }
}

Initialization of the derived instance variable did not occur when its lookup method was executed How to ensure that the derived instance variable is initialized when calling its method?

Solution

Well, first, the code cannot be compiled due to the lack of somelookup method

Anyway, beyond that, I think your problem is that your expectations are invalid due to the hierarchical operation of constructors

Superclass' constructors always run before subclasses', including initializers for subclass' variables (they actually run as part of constructors) Therefore, when you create a derived instance, the following occurs:

>First call the base constructor. > Call lookup (), which uses the implementation in derived. > Return > num, which is the default value at this time, because the derived constructor and initializer have not been run. > Val set to 0. > Derived initializers and constructors are running – calling lookup from this point on will return 10

In general, for this reason, calling non final methods from constructors is a bad idea. Many static analysis tools warn you not to do so. It is similar to letting the object reference leak during construction. You will eventually get an instance that invalidates the class level invariant (in your case, the derived num is "always" 10, but at some points it can be regarded as 0)

Edit: Please note that there is no other code for this special case. You can solve the problem by making num constant:

class Derived extends Base
{
  private static final int num = 10;
  ...

This will actually do what you want, because the static initializer runs when the class is loaded (it must happen before calling the constructor) However, this does assume that it applies to:

a) All instances of the class share the same num variable; b) Num never needs to be changed (if this is true, then (a) is automatically true)

This is obviously the case in the exact code you give, but I hope you may omit additional functionality to simplify

I @ r_ 419_ 2472 @ contains this for comparison and interest, not because it is a general solution to this "problem" (because it is not)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>