Rules for constructors

From: Alex Hunsley (lard_at_tardis.ed.ac.molar.uk)
Date: 03/17/04


Date: Wed, 17 Mar 2004 16:17:23 +0000

I just found quite an annoying thing some code I am maintaining...

Here is the essence of what happened:
(this is a runnable self-contained example)

public class B extends A {
        private int memberVariable = 0;
        
        public B(int param1, int param2) {
                super(param1, param2);
                
                System.out.println("memberVariable = "
                        + memberVariable);
        }

        protected void setUpSomeThings() {
                memberVariable = 7;
        }

        
        public static void main(String[] args) {
                B bInstance = new B(2, 3);
        }
}

class A {

        
        public A(int param1, int param2) {
                setUpSomeThings();
        }

        protected void setUpSomeThings() {
                // some code in here
        }
}

You'd expect the code to print out memberVariable=7, but it actually
prints out memberVariable=0.
This is because the constructor of B calls super(param1, param2), and by
stepping through the code in eclipse I could see that the java runtime
processes the call to setUpSomeThings() in super(..) *before* it gets
around to settings up the member variables in class B! Therefore, once
the setUpSomeThings in the subclass (B) has been called by the
constructor for A, the initialisation of the member variables in class B
s constructor happens, which sets the member variable to 0 and wipes out
the pervious value of 7.

Anyway, what exactly is the moral of this tale?

I suspect it's either
  a) always check your class is initialised,
    as per
http://www.javaworld.com/javaworld/jw-12-1998/jw-12-securityrules.html,
  but this is a bit security-paranoid

  b) never call non-final methods from your constructor
   (or else they will be overridden causing chaos as I have experienced
today)
  c) overridden methods should not access member variables that are
   from this class - should only access superclass member variables

any other suggestions?
What do people take a generally good rules for constructors?
I already practice the rule that you shouldn't do any populating or,
worse, realising of GUI items from a constructor.

alex



Relevant Pages

  • Re: Rules for constructors
    ... Alex Hunsley wrote: ... > constructor for A, the initialisation of the member variables in class B ... realising of GUI items from a constructor. ...
    (comp.lang.java.programmer)
  • Re: a question about classes
    ... doesn't calling the constructor result in mD and mS being ... The function iFconst has a return value of X, ... assign values to a new X object's member variables. ... This object is returned to the caller. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Rules for constructors
    ... > b) never call non-final methods from your constructor ... > c) overridden methods should not access member variables that are ... > from this class - should only access superclass member variables ... access any object state from these methods. ...
    (comp.lang.java.programmer)
  • Re: No use of initializer list
    ... "will not be used as member variables": ... compileable code (unless you are getting a compile error and the point ... this constructor, what x and y represent, about f, etc), so we can't ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Rules for constructors
    ... "Alex Hunsley" wrote in message ... > b) never call non-final methods from your constructor ... > (or else they will be overridden causing chaos as I have experienced ... Tim Ward ...
    (comp.lang.java.programmer)