Objects are constructed. You can never make a new object without invoking a constructor (and not just the constructor of the object’s actual class type, but also the constructor of each of its superclasses).
Suppose there is a Horse
class which extends Animal
(and obviously Animal
extends Object
). Now, this is how the
constructors are called after new Horse()
is invoked from main()
:
- main() calls new Horse()
- Horse() calls super()
- Animal() calls super()
- Object()
Constructors have no return type and their names must exactly match the class name. Typically, constructors are used to initialize instance variable as below:
So when you invoke new Foo("rohit", 12)
, an object of Foo
class is created with name
set as Rohit
and size
as 12
.
Below are the important rules for Constructors
1. If you don’t type a constructor into your class code, a default constructor will be automatically generated by the compiler. The default constructor (the one supplied by compiler) is ALWAYS a no-arg constructor.
Class Code (WhatYouType) | Compiler Generated Constructor Code |
---|---|
class Foo { } |
class Foo { Foo() { super(); } } |
2. Every constructor has, as its first statement, either a call to an overloaded constructor (this()
) or a call to the
superclass constructor (super()
), and if not it is inserted by the compiler. Remember, compiler always inserts a no-arg
call to super()
, it never passes any arguments.
class Foo { Foo() { } } |
class Foo { Foo() { super(); } } |
3. If you want a no-arg constructor and you’ve typed any other constructor(s) into your class code, the compiler won’t provide the no-arg constructor (or any other constructor) for you. In other words, if you’ve typed in a constructor with arguments, you won’t have a no-arg constructor unless you type it in yourself.
class Foo { Foo(String s) { super(); } } |
Code is the same. Compiler doesn’t insert anything here. |
4. Constructors can use any access modifier, including private. (A private constructor means only code within the class itself can instantiate an object of that type, so if the private constructor class wants to allow an instance of the class to be used, the class must provide a static method or variable that allows access to an instance created from within the class. Moreover, for a Singleton you are bound to make all constructors of class private.) Also note that the default constructor has the same access modifier as the class.
public class Foo { } |
public class Foo { public Foo() { super(); } } |
private class Foo { } |
private class Foo { private Foo() { super(); } } |
5. A call to super()
can be either a no-arg call or can include arguments passed to the super constructor. But
the compiler always inserts a no-arg call to super()
. So there would be a problem in the below case:
class Animal { Animal(String name) { } } class Horse extends Animal { Horse() { } } |
class Animal { Animal(String name) { } } class Horse extends Animal { Horse() { super(); // problem! } } |
As there is no no-arg constructor in Animal class, the call to super()
(inserted by the compiler) in Horse
class will
fail. In fact, the compiler won’t even compile the code on the left hand side.
You can solve this in two ways, either you can provide a no-arg constructor in Animal
class or you can
yourself type super("some name")
as first statement in the constructor in Horse
class.
6. You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs. Only static variables and methods can be accessed as part of the call to super() or this().
public class Animal { String name; Animal(String name) { this.name = name; } Animal() { this(getName()); // ok! this(getNickName()); // compiler error! getNickName(); // ok! } static String getName() { return "Horse"; } String getNickName() { return "Horsie"; } } |
Now let’s understand the above code:
- line 9 is ok as the method
getName()
is static so it belongs to the class and can be accessed without the need of any object of the class. - line 10 is not ok as the method
getNickName()
is not static and to access such a method you need an object first and from constructor chaining we know that until and unless super type constructors are called object isn’t created. - line 11 is fine because super type constructors are called before calling
getNickName()
.
Some more obvious rules which you already know but is worth mentioning
7. Abstract classes have constructors, and those constructors are always called when a concrete subclass is instantiated.
8. Interfaces do not have constructors. Interfaces are not part of an object’s inheritance tree.
9. A constructor can be invoked from within another constructor only. You cannot invoke a constructor from anywhere else.
10. Lastly, constructors are never inherited. They aren’t methods. Constructors can’t be overridden (because they aren’t methods and only instance methods can be overridden).
Q&A
Q1. What is the output of the below program?
A. abc
B. Empty string
C. Won’t compile
D. Runtime error
Q2. What is the result?
A. BD
B. DB
C. BDC
D. DBC
E. Compilation fails
Q3. What is the result?
A. subsub
B. sub subsub
C. alpha subsub
D. alpha sub subsub
E. Compilation fails
F. An exception is thrown at runtime
Q4.
What is the result?
A. h hn x
B. hn x h
C. b h hn x
D. b hn x h
E. bn x h hn x
F. b bn x h hn x
G. bn x b h hn x
H. Compilation fails