0

Is calling super() constructor should be the very first line of the constructor? If so then why? Why can't I do some simple limited calculations before constructor call, for example, constructor parameters calculation?

I found a situation with inner class constructors which can be called with closure specification:

class A {
    class Inner1 {
        Inner1() {
            // do something
        }
    }
}

class B {
    A a1 = new A();
    A a2 = new A();

    class Inner2 extends A.Inner1 {
         Inner2(boolean sel) {
             (sel?a1:a2).super();
         }
    }

}

This case shows we can want to select enclosing instance for a base class constructor. Why selection logic should be so limited? Why one can't write something like this

if( sel ) {  
    a1.super();
}
else {
    a2.super();
}

ADDITION

By my question I mean that the limitation could be like in the following case:

public class Base {

private final String content;

public Base(String content) {
    this.content = content;
}

public String getContent() {
    return content;
}

}


public class Derived extends Base {

public Derived(String content) {
    super(String.format("Current value of content is %s.", getContent()));
}


}

In latter case I:

1) Fulfilling the requirement of super() to be in the first line

2) Violating the order of construction

3) Get a compiler error "Cannot refer to an instance method while explicitly invoking a constructor"

So, why we can't abolish "first line requirement" and rely only on errors like the last one?

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385
  • 2
    `super()` has to be placed as the first line of a constructor call if you use it - but check this thread: http://stackoverflow.com/questions/9675431/solution-when-super-cannot-be-first-line-of-constructor-in-java or this: http://stackoverflow.com/questions/1168345/why-does-this-and-super-have-to-be-the-first-statement-in-a-constructor – wkl May 23 '12 at 20:49
  • Thanks! Workarounds are interesting but it is also interesting, why Java was made so, i.e. what bad if I do something before calling super? For example, I could be just obliged not to access instance members until calling super. – Suzan Cioc May 23 '12 at 20:54
  • @SuzanCioc If you do something before calling `super()`. Java will stop your program and tell you to fix it. – Hunter McMillen May 23 '12 at 20:55
  • 1
    @Suzan Cioc, second link provided by birryree covers that question – dantuch May 23 '12 at 20:56
  • @Suzan There are languages (python) that allow to call the constructor of the super class later or not at all. That obviously can have bad consequences, but then we all know that calling `super()` first doesn't solve all problems and creates a slew of new ones. It's a simplification though, because it means we don't have to split object allocation and initialization in two separate parts. And I assume it avoids one kind of problems that would otherwise come up regularly. – Voo May 23 '12 at 20:59
  • Pls see my addition. I don't wish to deal with uninitialized instances like in C++, I just wonder, why can't we rely on checks like "Cannot refer to an instance method while explicitly invoking a constructor"? – Suzan Cioc May 23 '12 at 21:11

2 Answers2

3

Yes, a call to super() is required as the very first call in a constructor.

So much so that if you leave it out the compiler will (attempt to) insert the call for you. To understand the why, you would need to understand the philosophies of Java's designers. Gosling has always been in the camp of computer scientists that believe that accessing partially initialized objects is one of the bigger sources of bugs in computer programs. And as such he designed a strict initialization hierarchy that would help to alleviate this problem. Wether you agree with the philosophy is moot - but its important to realize that its as important a concept in Java as for example, references vs pointers, or real, bounded arrays. It should be noted that even languages like Objective C that allow you to invoke initialization at any time, go to great length to enforce initialization chaining, except that they need to do so via convention, as opposed to strict language rules.

I'm not sure what you were trying to illustrate in your example - but after years of development with Java I doubt you will find many cases where you really need to perform logic before invoking super.

Perception
  • 79,279
  • 19
  • 185
  • 195
0

Constructor calls are chained with super of every class in hierarchy being invoked before constructor of that class is invoked. As all classes in Java inherited from object class, so constructor of Object class is invoked first for every class with reason being that memory allocation for object is done by constructor of Object class

ejb_guy
  • 1,125
  • 6
  • 6
  • But what is the principal difference if I write one long but single expression with `super()` and if I write some multiline code? – Suzan Cioc May 23 '12 at 20:55
  • can you pls explain. Basically if constructor of Object class is not executed than you dont have object to work with. And to ensure that Object's constructor is called, calling super() has to be first line – ejb_guy May 23 '12 at 20:58
  • look at my question pls. I provided two codes of extended constructor, which are identical by logic, but only first of which are allowed by Java – Suzan Cioc May 23 '12 at 20:59