Best way to handle multiple constructors in Java

后端 未结 9 1452
没有蜡笔的小新
没有蜡笔的小新 2020-12-02 07:00

I\'ve been wondering what the best (i.e. cleanest/safest/most efficient) way of handling multiple constructors in Java is? Especially when in one or more constructors not al

9条回答
  •  隐瞒了意图╮
    2020-12-02 07:45

    Some general constructor tips:

    • Try to focus all initialization in a single constructor and call it from the other constructors
      • This works well if multiple constructors exist to simulate default parameters
    • Never call a non-final method from a constructor
      • Private methods are final by definition
      • Polymorphism can kill you here; you can end up calling a subclass implementation before the subclass has been initialized
      • If you need "helper" methods, be sure to make them private or final
    • Be explicit in your calls to super()
      • You would be surprised at how many Java programmers don't realize that super() is called even if you don't explicitly write it (assuming you don't have a call to this(...) )
    • Know the order of initialization rules for constructors. It's basically:

      1. this(...) if present (just move to another constructor)
      2. call super(...) [if not explicit, call super() implicitly]
      3. (construct superclass using these rules recursively)
      4. initialize fields via their declarations
      5. run body of current constructor
      6. return to previous constructors (if you had encountered this(...) calls)

    The overall flow ends up being:

    • move all the way up the superclass hierarchy to Object
    • while not done
      • init fields
      • run constructor bodies
      • drop down to subclass

    For a nice example of evil, try figuring out what the following will print, then run it

    package com.javadude.sample;
    
    /** THIS IS REALLY EVIL CODE! BEWARE!!! */
    class A {
        private int x = 10;
        public A() {
            init();
        }
        protected void init() {
            x = 20;
        }
        public int getX() {
            return x;
        }
    }
    
    class B extends A {
        private int y = 42;
        protected void init() {
            y = getX();
        }
        public int getY() {
            return y;
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            B b = new B();
            System.out.println("x=" + b.getX());
            System.out.println("y=" + b.getY());
        }
    }
    

    I'll add comments describing why the above works as it does... Some of it may be obvious; some is not...

提交回复
热议问题