This question already has answers here:
What is the actual use of the default constructor in java?
(7 answers)
Closed 4 years ago.
There is something that I don't understand about the real role of the default constructor in java. In the official tutorial about object creation :
Creating Objects
All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor (Object does have one), the compiler will reject the program.
And in the docs about the Default Constructor (§8.8.9)
8.8.9. Default Constructor
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
So even the default constructor of the class Object has an empty body. And I know that the default constructor does NOT initialize fields to their default values, because it's the compiler who does that :
Default Values
It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler.
What I don't understand is, if we didn't declare a constructor, what does the default constructor really do ?
what does the default constructor really do?
It calls super(). As per all your quotations. And does nothing else. JLS #8.8.9:
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
i.e. it does nothing else. For those who believe it initializes instance variables please see JLS #12.5 where the contrary is asserted.
In Java, if you don´t declare any constructor the compiler create a default constructor and this constructor call to super() method, that is parents constructor. And in this process, inits instance variables like no-default constructors.
What I don't understand is, if we didn't declare a constructor, what
does the default constructor really do ?
By default, if no constructor is declared, a class has a default constructor with no args. I think that's why, by default all constructor calls super(). It follows probably the convention over configuration principle.
Whatever you declare a public constructor or you don't declare at all constructor, first instruction of the constructor is super().
That's why if you define in a class MyClass a constructor with args MyClass(String s) without keeping a constructor with no argument, constructor of MyClass subclasses cannot compile while it doesn't precise in their first instruction, the call to an existing parent constructor, in the exemple, it would be super(String ...).
Here an example :
public class MyClassWithNoArg{
public MyClassWithNoArg(){
}
}
MyClassWithNoArg constructor calls super() in this first instruction even if it not specified in the source code.
It is as if it is written in this way :
public class MyClassWithNoArg{
public MyClassWithNoArg(){
super();
}
}
Imagine now another class MyClassWithArg:
public class MyClassWithArg{
public MyClassWithNoArg(String s){
}
}
And MySubclass a subclass of MyClassWithArg
public class MySubclass extends MyClassWithArg{
public MySubclass (String s){
}
public MySubclass (){
}
}
In both cases, it will not compile since as explained previously all constructors call by default the default constructor (super()) of their parent but here the parent,MyClassWithArg, has no constructor with no arg. So, it doesn't compile.
So to solve the problem, you have to call the super constructor which exists.
public class MySubclass extends MyClassWithArg{
public MySubclass (String s){
super(s);
}
public MySubclass (){
super("");
}
}
Now, compilation is OK.
Without constructor no one can create a object of a class. Now if programmer does not add any constructor with a class then java compiler added a constructor with that class before compilation,which is known as default constructor in java.
But if programmer adds any kind of constructor(with argument or without argument) then that becomes user defined constructor and no constructor 'll be added via java compiler.
Now question is what does constructor do.
allocates memory for new object
if user defines any other operation like initialising variable that is done.
Related
This question already has answers here:
Why call super() in a constructor?
(8 answers)
Closed 5 years ago.
I'm a Java beginner learning about Java compiler rules as below:
If the class has no super class, extend it to Object class
If the class has no constructor, add a default no-parameter constructor
If the first line of the constructor is not "super()" or "this()", add "super()" to call the default constructor of the super class.
I understand that all objects we create are derived from the super class Object.
My question is what does the constructor in the Object class do when called?
Edit: My question is about what the constructor does in the class Object? I'm aware that subclasses call superclass's constructor by default.
For example, I have the following code (where I explicitly extend to Object and call super() to illustrate what the compiler does). My question is, what does the call to super() do?
public class Person extends Object
{
private String name;
public Person(String n)
{
super();
this.name = n;
}
}
My question is, what does the call to super() do?
It calls the default constructor for java.lang.Object. And to answer what you seem to be really asking, from the Java Language Specification, #8.8.9
8.8.9. Default Constructor
If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:
The default constructor has the same accessibility as the class (§6.6).
The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
The default constructor has no throws clauses.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
Note the final paragraph.
All Java classes that don't have any explicit superclass, extend from Object, except for Object itself. There's no need to make it explicit in your code, the compiler will take care of.
Also, the super() call in the constructor will invoke the constructor of Object. If you look at the implementation, you'll see that Object doesn't have any constructor at all, so it'll use an implicit empty constructor which does nothing. Details such as constructing a vtable to make sure that the inherited methods are there to use or initialising the object's monitor are not part of the constructor but are performed by the JVM implementation when the new operator is called.
public Object() {
}
The Object class has few methods that come handy in most of the classes. For example, the infamous toString() is implemented in the Object class. Also, the hashCode() is implemented there.
I'd recommend you to have a deep look at the Object.class file to understand what methods are inherited in every single Java class.
Regarding your 3 rules at the top, are "good" for academic purposes but never used in reality. You'll never see an explicit extends Object, and only call the super() or this() when you need to overwrite the default behaviour.
Also, avoid abusing of inheritance and use more composition (implement an interface), although, it depends on the every use case.
For example, I have the following code (where I explicitly extend to
Object and call super()). My question is, what does the call do
super() do?
Actually, Object() does nothing.
Now you should not reduce the constraint to invoke super() (with args or not) for any subclass constructor to the case where you have a class that doesn't extend a class explicitly.
This case is the only one where invoking super() may seem not really useful.
But as soon a class extends a class distinct from Object, this constraint makes really sense as the child construction has to apply first its parent construction.
But the language specifies this point in a general way. It has no exception for classes that extend directly Object.
Probably because, it makes things more simple and that is not a real constraint as the compiler adds for you the call to the super default constructor : super().
Why should a class call the call the Objects default constructor of the class Objects when the class already has a parametrized constructor and a unparametrized constructor?
Example
public abstract class Foo{
private int dim1;
public Foo(int dim1) {
super();
this.dim1 = dim1;
}
public Foo() {
this.dim1 = 0;
}
}
2. Why isn't the super() method called in the unparametrized constructor in the example above?
What could happen if I forget or I don't want to call the constructor in the Object class with super() ?
Does it matter if the class which calls the super() method (Unparametrized Object's class constructor) is abstract or not ?
Why should a class call the call the Objects default constructor of the class Objects when the class already has a parametrized constructor and a unparametrized constructor?
Just because of you have it, it doesn't mean it gets called automatically. You have to call it and that is where object instantiation begins.
Why isn't the super() method called in the unparametrized constructor in the example above?
It is not a method. It is just invoking the super class default constructor. Do you know , if you didn't call it, the Java compiler automatically inserts that statement while giving you byte code. So you need not write that super() in child constructors unless you want to call specific constructor .
What could happen if I forget or I don't want to call the constructor in the Object class with super() ?
Don't worry. As said above, compiler inserts it for you.
Does it matter if the class which calls the super() method (Unparametrized Object's class constructor) is abstract or not ?
Yes, abstract or not doesn't matter. It just calls the super class constructor.
1) You probably shouldn't. It is unnecessary. It is an extra line of code which doesn't do anything.
2) Because explicitly calling super() is entirely unnecessary if your object does not extend a class other than Object (as all classes do). You could remove it from the first constructor and nothing would change. The code would compile identically.
3) Nothing. You're not required to do it.
4) This makes no difference.
If I create an object of a sub-class with no constructors, then I know that the compiler will implicitly provide a default constructor. What if I create a constructor in the sub-class and try to access the super class constructor using the super keyword, and, now, the super class has no constructor in it. Will the compiler provide a default constructor for the super class as well?
Yes, if there is no specified constructor, there is always default empty constructor
Does the compiler provides a default constructor for the super class also???
The default constructor will be there whether or not there is a subclass that needs it. The default is supplied when the parent is compiled, not later.
...What if I created sub class Constructor and trying to access the super class constructor using the super keyword,and the super class has no constructor in it.
But it does: The default one.
It goes like this.
Lets speak about Object which is the supermost class in java, If you open an editor and just make a class, then it is presumed that It is extending Object. Every class in Java extends from Object. If you do not write your own constructor then Compiler will provide one.
But if you write your own constructor let's say a constructor with one argument, compiler will not provide you with any constructor.
Now lets say taht you extend the above class, then compiler will complain you saying that the superclass does not have a default constructor rather a custom constructor so you need to make one constructor for this child class since first constructor which is called starts from the supermost class that is OBJECT and then proceeds down the line.
Hope this answers comprehensively,
Thanks.
Yes the super always occurs even if you didnt explicit declare
public class FatherTest {
}
public class SonTest extends FatherTest{
public SonTest(String sonName){
super(); // this will always occurs
}
}
If you don't write a constructor for a class, the compiler will implicitly add an empty one for you.
That means this:
public class X {
}
is identical to this:
public class X {
public X() {
// there's also an implicit super(); added here, but that's not directly relevant
}
}
If the super class doesn't have explicit constructor, then an implicit default constructor will be added to it. So your super() will invoke that.
If the super class only have some constructors with parameters. Then super() in the sub-class won't compile. You have to explicitly use one of the defined super-class constructor super(param1, param2, ...), since super() will be called if you don't call it.
While studying for my finals, I came across the following statement in the book from which I am currently studying. Considering the following code :
class A {
public A(int x) { }
}
class B extends A {
public B(int x ) { }
}
is it mandatory to call the constructor of class A in the constructor of class B(super(x)). The book states that it's not mandatory, because they have the exact number and type of parameters. But when I try this in a java compiler, the following error gets thrown :
constructor A in class A cannot be
applied to given types; required:
int found: no arguments reason:
actual and formal argument lists
differ in length
The compiler automatically inserts super() in the beginning.
However, even constructors arguments, super() (without arguments) is added which invokes the default constructor of the superclass. And you don't have one, hence the error.
You have to specify super(x) (to invoke A(x)), or define a no-argument constructor.
By the way, Eclipse compiler gives a way better error message:
Implicit super constructor A() is undefined. Must explicitly invoke another constructor
It looks like the compiler tries to create a call to the superclasses default constructor with super(), which isn't avaliable:
required: int
found: no arguments
But back to your book: I've never heard of a rule that you can skip the super statement in a constructor if the actual constructor has the exact same parameter list as a constructor in the direct superclass. Only a call to the superclass's default constructor is added implicitly (super()) but that requires that the superclass has a default constructor.
In contrast to what's written in your book (or in contrast to your understanding of the written text), here's a sentence from the language spec:
If a constructor body does not begin with an explicit constructor invocation
and the constructor being declared is not part of the primordial class Object, then
the constructor body is implicitly assumed by the compiler to begin with a super
class constructor invocation “super();”, an invocation of the constructor of its
direct superclass that takes no arguments.
If you have a the base class having a default constructor (no-arg constructor), when you extend B, you don't need to explicitly call super() because it is called any way.
But when you have a constructor with arguments, when making the contructor with parameters in B, you need to pass in super() a parameter for A
example :
class A {
public A(int x) { }
}
class B extends A {
public B(int x )
{
super(x); // need to specify the parameter for class A
//...
}
}
This happens when you dont have a default constructor and you are creating an instance with default one. Because If you have any Parameterized constructor then compiler will not insert the default one for you, instead you have to define.
It is neccessary to call constructor of super class in case of Java. Therefore, whenever you generate constructor of sub class, super class' constructor is self created by IDE.
It is because whenever base class constructor demands arguments, compiler thinks they are to be filled by base class constructor. In case of default constructor, it is OK. No need to call super() in sub class.
I saw this question in one of my question papers:
Why should the derived class constructor always access base class constructor?
I'm wondering whether the question is valid?
So that you may have a valid object of type "Base" before you start messing with the inherited functionality in your derived object!
It's not valid. There's no 'should' about it: it must, and the compiler enforces it, by calling the base class's default constructor if it exists, and giving you a compile error if it doesn't, which forces you to call one of the existing constructors.
There is one exception to always, a default constructor in a superclass isn't usually called explicit.
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
Because the base class may do work you are not aware of.
Because the base class may have members that require initialization.
Since the derived class constructor wants to inherits from the base class constructor, it is necessary to call the base class constructor. Otherwise, if you don't, you will not inherit values initialised in base class constructor.
Calling a superclass constructor is not a must but a should paired with a strong advise - as long as the superclass has a default constructor. Otherwise the compiler forces you to call at least one of the superclasses constructors.
If the default constructor is present, it's called anyway, even without an explicit super() statement in the subclasses construtor.
A visible part of class construction is the initialization of fields. But there's more under the hood (memory allocation, registration, etc). All this has to be done for all superclasses when a derived class is created.
You do not need to call constructor when there is a default constructor (i.e a no-argument constructor) present in the base class. When there is a constructor with arguments present and no default constructor, then you don't need to declare a constructor in the child class.
You only need to initialize the child class constructor when there is no default constructor present in the parent class.
Example :
class A {
public int aInstanceVariable;
public A(int aInstanceVariable) {
this.aInstanceVariable = aInstanceVariable;
}
}
class B extends A {
// In this case we have to call super in base class constructor
}
However, when public A() {} is present in class A, there is no need to initialize the child class constructor.