Why can't this() and super() both be used together in a constructor?

后端 未结 9 630
栀梦
栀梦 2020-12-12 17:17

Why can\'t this() and super() both be used together in a constructor?

What is the reason for incorporating such a thing?

相关标签:
9条回答
  • 2020-12-12 17:42

    Compare example below. Class FirstChild sets instance variable name in 2 constructors as calling the second constructor from the first one is excluded by need to call super().

    In class SecondChild there is introduced third private constructor that takes 2 parameters – first one passed to supper() and the second one used to set name. First 2 constructors are calling the third one. Super() is called exactly once, also instance variable is set only in one constructor. Code produces the same result without need to call super() and this() in same constructor.

    class FirstChild extends ConstructorTest{
        private String name = null;
        public FirstChild(){
            super("super text 1");
            //this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
            name = "Unknown";
        }
        public FirstChild(String name){
            super("super text 2");
            this.name = name;
        }
        public String getName(){
            return name;
        }
    }
    
    class SecondChild extends ConstructorTest{
        private String name = null;
        public SecondChild(){
            this("super text 1", "Unknown");
        }
        public SecondChild(String name){
            this("super text 2", name);
        }
        private SecondChild(String superStr, String name)
        {
            super(superStr);
            this.name = name;
        }
        public String getName(){
            return name;
        }
    }
    
    public class ConstructorTest{
        public ConstructorTest(String str){
            System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
        }
        public static void main(String... args)
        {
            System.out.println("Hello from main, FirstChild results:");
            FirstChild fc1 = new FirstChild();
            FirstChild fc2 = new FirstChild("John");
            System.out.println("           child fc1 name: " + fc1.getName());
            System.out.println("           child fc2 name: " + fc2.getName());
            System.out.println("Hello from main, SecondChild results:");
            SecondChild sc1 = new SecondChild();
            SecondChild sc2 = new SecondChild("John");
            System.out.println("           child sc1 name: " + sc1.getName());
            System.out.println("           child sc2 name: " + sc2.getName());
        }
    }
    
    0 讨论(0)
  • 2020-12-12 17:46

    super() - refers immediate parent class instance. Can be used to invoke immediate parent class method. this() - refers current class instance. Can be used to invoke current class method.

    0 讨论(0)
  • 2020-12-12 17:47

    this(...) will call another constructor in the same class whereas super() will call a super constructor. If there is no super() in a constructor the compiler will add one implicitly.

    Thus if both were allowed you could end up calling the super constructor twice.

    Example (don't look for a sense in the parameters):

    class A {
      public A() {
        this( false );
      }
    
      public A(boolean someFlag) {
      }
    }
    
    class B extends A {
      public B() {
        super();
      }
    
      public B( boolean someFlag ) {
        super( someFlag );
      }
    
      public B ( int someNumber ) {
        this(); //
      }
    } 
    

    Now, if you call new B(5) the following constructors are invoked:

         this( false);
    A() ---------------> A(false)
    ^
    |
    | super(); 
    |
    |     this();
    B() <--------------- B(5)  <--- you start here
    

    Update:

    If you were able to use this() and super() you could end up with something like this:

    (Attention: this is meant to show what could go wrong, if you were allowed to do that - which you fortunately aren't)

         this( false);
    A() ---------------> A(false)
    ^                    ^
    |                    |
    | super();           | super( true ); <--- Problem: should the parameter be true or false? 
    |                    |
    |     this();        |
    B() <--------------- B(5)  <--- you start here
    

    As you can see, you'd run into a problem where the A(boolean) constructor could be invoked with different parameters and you'd now have to somehow decide which should be used. Additionally the other constructors (A() and B()) could contain code that now might not get called correctly (i.e. out of order etc.) since the call to super( true ) would circumvent them while this() wouldn't.

    0 讨论(0)
  • 2020-12-12 17:48

    There is a difference between super() and this().

    super()- calls the base class constructor whereas
    this()- calls current class constructor.

    Both this() and super() are constructor calls.
    Constructor call must always be the first statement. So you either have super() or this() as first statement.

    0 讨论(0)
  • 2020-12-12 17:50

    Both this() and super() are constructor calls, and constructor call must be the first (and only first) call in a constructor. Otherwise, the Object constructor will be called more than once when instantiating a single object.

    0 讨论(0)
  • 2020-12-12 17:53

    Because it doesn't make sense. A constructor has to either call this() or super() (implicitly or explicitly). this() calls another constructor which has to call either this() or super() etc as before. A constructor that called both this() and super() would therefore ultimately call super() twice.

    0 讨论(0)
提交回复
热议问题