Java requires that if you call this() or super() in a constructor, it must be the first statement. Why?
For example:
public class MyClass {
public MyClass(int x) {}
}
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
int c = a + b;
super(c); // COMPILE ERROR
}
}
The Sun compiler says "call to super must be first statement in constructor". The Eclipse compiler says "Constructor call must be the first statement in a constructor".
However, you can get around this by re-arranging the code a little bit:
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
super(a + b); // OK
}
}
Here is another example:
public class MyClass {
public MyClass(List list) {}
}
public class MySubClassA extends MyClass {
public MySubClassA(Object item) {
// Create a list that contains the item, and pass the list to super
List list = new ArrayList();
list.add(item);
super(list); // COMPILE ERROR
}
}
public class MySubClassB extends MyClass {
public MySubClassB(Object item) {
// Create a list that contains the item, and pass the list to super
super(Arrays.asList(new Object[] { item })); // OK
}
}
So, it is not stopping you from executing logic before the call to super. It is just stopping you from executing logic that you can't fit into a single expression.
There are similar rules for calling this()
. The compiler says "call to this must be first statement in constructor".
Why does the compiler have these restrictions? Can you give a code example where, if the compiler did not have this restriction, something bad would happen?
Before you can construct child object your parent object has to be created. As you know when you write class like this:
it turns to the next (extend and super are just hidden):
First we create an
Object
and then extend this object toMyClass
. We can not createMyClass
before theObject
. The simple rule is that parent's constructor has to be called before child constructor. But we know that classes can have more that one constructor. Java allow us to choose a constructor which will be called (either it will besuper()
orsuper(yourArgs...)
). So, when you writesuper(yourArgs...)
you redefine constructor which will be called to create a parent object. You can't execute other methods beforesuper()
because the object doesn't exist yet (but aftersuper()
an object will be created and you will be able to do anything you want).So why then we cannot execute
this()
after any method? As you knowthis()
is the constructor of the current class. Also we can have different number of constructors in our class and call them likethis()
orthis(yourArgs...)
. As I said every constructor has hidden methodsuper()
. When we write our customsuper(yourArgs...)
we removesuper()
withsuper(yourArgs...)
. Also when we definethis()
orthis(yourArgs...)
we also remove oursuper()
in current constructor because ifsuper()
were withthis()
in the same method, it would create more then one parent object. That is why the same rules imposed forthis()
method. It just retransmits parent object creation to another child constructor and that constructor callssuper()
constructor for parent creation. So, the code will be like this in fact:As others say you can execute code like this:
also you can execute code like this:
But you can't execute code like this because your method doesn't exists yet:
Also you are obliged to have
super()
constructor in your chain ofthis()
methods. You can't have an object creation like this: