0

Using Java I am trying to initialise member variables at declaring, but for some reason the variables stay at their default values e.g. 0, null etc.

Please see a snippet of example code which demonstrates what I'm trying to accomplish:

public class B extends A {

Map<Integer, Integer> map = new HashMap <Integer, Integer>();
int number = 10;

public B() {
  super();
}

public Map getMap() {
  return map;
}

public int getNumber() {
  return number;
}

}

The important part of the code are that it is a subclass, and that I'm trying to initialise two member variables at declaration. When I step into the constructor the values of the map and number are null and 0 respectively, what is the reason for this?

LDM91
  • 437
  • 1
  • 7
  • 16
  • 2
    IMO snippets should be cut-and-paste, which this clearly isn't--that makes diagnosing issues more difficult than it needs to be. – Dave Newton May 28 '12 at 16:35
  • Do you have the same members in your `A`class? – juergen d May 28 '12 at 16:35
  • It's impossible to say at the moment. Please provide a short but *complete* program which demonstrates the problem. – Jon Skeet May 28 '12 at 16:35
  • (And... are they null *after* the call to `super()`? This is really the only important question you should answer. Oh, as per JohnB's answer. – Dave Newton May 28 '12 at 16:40
  • I didn't cut-and-paste my complete program as I am extending a JTable and thought it would do more harm than good to include everything. The only member variables my subclass are the HashMap and int included in the snippet, with names that are unique. I have stepped into the class with a debugger and both before and after the constructor the values remain uninitialised. – LDM91 May 28 '12 at 16:43
  • 2
    @LDM91 Nobody's asking for the complete code--rather an [SSCCE](http://sscce.org/). I find it impossible to believe they're not initialized after the ctor unless your JDK/JVM is completely broken, which I think unlikely. The code, corrected, as posted, initializes the properties as you would expect, when they should be initialized. Printing the values after `super()` prints `10` and an empty map. – Dave Newton May 28 '12 at 16:44
  • Apologies everyone, it appears it may have been a syntax error. Thank you for highligting the importance ofproviding a SSCCE - after I put the code into a proper example to post, it started behaving as expected! – LDM91 May 28 '12 at 17:07

2 Answers2

4

By spec, the constructor of the base class is executed before initializing the members of class B.

See also here: Java Constructor and Field Initialization Order

Community
  • 1
  • 1
JohnB
  • 13,315
  • 4
  • 38
  • 65
0

My guess is here is what is happening:

    class A {
        protected Map<Integer,Integer> map;
        protected int number;

        public A() {
            map=new Map() {{ //This is just initializing the map
                put(1,1);
            }}
            number=5;
        }
    }

    public class B extends A {

        Map<Integer, Integer> map = new HashMap <Integer, Integer>();
        int number = 10;

        public B() {
          super();
        }
    }

Here's what happens in the the B constructor, from the compiler's point of view:

  1. Go to the no-param constructor for A.
  2. Make a new Map called map.
  3. Make a new int called number.
  4. Initialize map with value 1 at key 1.
  5. Initialize number to 5.
  6. Done here, go to the rest of B's constructor.
  7. Make a new Map called map. This will override the variable called map constructed in A.
  8. Make a new int called number. This will override the variable called number constructed in A.
  9. (Don't initialize map.)
  10. (Don't initialize number.)
  11. Done.

I hope this clears things up. If you don't want that to happen, initialize B's fields in its own constructor.

LastStar007
  • 725
  • 1
  • 8
  • 21
  • That would not explain the behavior OP claimed they were seeing, which is that `map` was `null` and `number` was `0`. – Dave Newton May 28 '12 at 17:24
  • As I clarified in my comments the member variables in the subclass had unique names which did not match anything in the super class. When I was stepping through the program, it would go into the constructor and call super() without going up to the member variables and initializing them first. I haven't been able to re-create it, but I suspect that it was perhaps a syntactical error (most likely too many or too few braces as when I commented out the majority of the class I was able to get it working). – LDM91 May 28 '12 at 21:05