In the code that I have provided the overloaded constructor with argument which makes a call to the no-args constructor, which inturn should call the constructor of the object class in this case. So how does using the this() keyword execute the program correctly but not a direct call to the constructor.
public class S {
S() {
System.out.println("S()");
}
S(int i) {
this();
S();// The method S is undefined for type S
System.out.println("S(int i)");
}
public static void main(String[] args) {
S obj1 = new S();
System.out.println("----------");
S obj2 = new S(10);
System.out.println("----------");
}
}
Syntactically, S() is a method invocation, but you do not have a method called S.
this(); is special syntax for using another constructor in the same class.
To illustrate this point, I added:
void S() {
System.out.println("Method S()");
}
It now compiles, and the output is:
S()
----------
S()
Method S()
S(int i)
----------
A constructor is defined to initialize (construct) objects, therefore you can't call it.
S s = new S();//Correct
S(); //Incorrect, you are calling a method not a constructor.
new S();//Correct
this() is used to to pass arguments to constructor of the same class.
super() is used to pass arguments to parent constructor.
This is called explicit constructor invocation.
Note that when invoking a constructor from another constructor, it must be the first statement of the constructor else it won't compile.
How to invoke other constructors of the same class is defined by The Java Language Specification, section 8.8.7.1 Explicit Constructor Invocations:
• Alternate constructor invocations begin with the keyword this
(possibly prefaced with explicit type arguments). They are used to
invoke an alternate constructor of the same class.
• Superclass constructor invocations begin with either the keyword
super (possibly prefaced with explicit type arguments) or a Primary
expression. They are used to invoke a constructor of the direct
superclass.
Related
What exactly is a default constructor — can you tell me which one of the following is a default constructor and what differentiates it from any other constructor?
public Module() {
this.name = "";
this.credits = 0;
this.hours = 0;
}
public Module(String name, int credits, int hours) {
this.name = name;
this.credits = credits;
this.hours = hours;
}
Neither of them. If you define it, it's not the default.
The default constructor is the no-argument constructor automatically generated unless you define another constructor. Any uninitialised fields will be set to their default values. For your example, it would look like this assuming that the types are String, int and int, and that the class itself is public:
public Module()
{
super();
this.name = null;
this.credits = 0;
this.hours = 0;
}
This is exactly the same as
public Module()
{}
And exactly the same as having no constructors at all. However, if you define at least one constructor, the default constructor is not generated.
Reference: Java Language Specification
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
Clarification
Technically it is not the constructor (default or otherwise) that default-initialises the fields. However, I am leaving it the answer because
the question got the defaults wrong, and
the constructor has exactly the same effect whether they are included or not.
A default constructor is created if you don't define any constructors in your class. It simply is a no argument constructor which does nothing. Edit: Except call super()
public Module(){
}
A default constructor is automatically generated by the compiler if you do not explicitly define at least one constructor in your class. You've defined two, so your class does not have a default constructor.
Per The Java Language Specification Third Edition:
8.8.9 Default Constructor
If a class contains no constructor
declarations, then a default
constructor that takes no parameters
is automatically provided...
Hi. As per my knowledge let me clear the concept of default constructor:
The compiler automatically provides a no-argument, default constructor
for any class without constructors. This default constructor will call
the no-argument constructor of the superclass. In this situation, the
compiler will complain if the superclass doesn't have a no-argument
constructor so you must verify that it does. If your class has no
explicit superclass, then it has an implicit superclass of Object,
which does have a no-argument constructor.
I read this information from the Java Tutorials.
Java provides a default constructor which takes no arguments and performs no special actions or initializations, when no explicit constructors are provided.
The only action taken by the implicit default constructor is to call the superclass constructor using the super() call. Constructor arguments provide you with a way to provide parameters for the initialization of an object.
Below is an example of a cube class containing 2 constructors. (one default and one parameterized constructor).
public class Cube1 {
int length;
int breadth;
int height;
public int getVolume() {
return (length * breadth * height);
}
Cube1() {
length = 10;
breadth = 10;
height = 10;
}
Cube1(int l, int b, int h) {
length = l;
breadth = b;
height = h;
}
public static void main(String[] args) {
Cube1 cubeObj1, cubeObj2;
cubeObj1 = new Cube1();
cubeObj2 = new Cube1(10, 20, 30);
System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
System.out.println("Volume of Cube1 is : " + cubeObj2.getVolume());
}
}
General terminology is that if you don't provide any constructor in your object a no argument constructor is automatically placed which is called default constructor.
If you do define a constructor same as the one which would be placed if you don't provide any it is generally termed as no arguments constructor.Just a convention though as some programmer prefer to call this explicitly defined no arguments constructor as default constructor. But if we go by naming if we are explicitly defining one than it does not make it default.
As per the docs
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
Example
public class Dog
{
}
will automatically be modified(by adding default constructor) as follows
public class Dog{
public Dog() {
}
}
and when you create it's object
Dog myDog = new Dog();
this default constructor is invoked.
default constructor refers to a constructor that is automatically generated by the compiler in the absence of any programmer-defined constructors.
If there's no constructor provided by programmer, the compiler implicitly declares a default constructor which calls super(), has no throws clause as well no formal parameters.
E.g.
class Klass {
// Default Constructor gets generated
}
new Klass(); // Correct
-------------------------------------
class KlassParameterized {
KlassParameterized ( String str ) { //// Parameterized Constructor
// do Something
}
}
new KlassParameterized(); //// Wrong - you need to explicitly provide no-arg constructor. The compiler now never declares default one.
--------------------------------
class KlassCorrected {
KlassCorrected (){ // No-arg Constructor
/// Safe to Invoke
}
KlassCorrected ( String str ) { //// Parameterized Constructor
// do Something
}
}
new KlassCorrected(); /// RIGHT -- you can instantiate
If a class doesn't have any constructor provided by programmer, then java compiler will add a default constructor with out parameters which will call super class constructor internally with super() call. This is called as default constructor.
In your case, there is no default constructor as you are adding them programmatically.
If there are no constructors added by you, then compiler generated default constructor will look like this.
public Module()
{
super();
}
Note: In side default constructor, it will add super() call also, to call super class constructor.
Purpose of adding default constructor:
Constructor's duty is to initialize instance variables, if there are no instance variables you could choose to remove constructor from your class. But when you are inheriting some class it is your class responsibility to call super class constructor to make sure that super class initializes all its instance variables properly.
That's why if there are no constructors, java compiler will add a default constructor and calls super class constructor.
When we do not explicitly define a constructor for a class, then java creates a default constructor for the class. It is essentially a non-parameterized constructor, i.e. it doesn't accept any arguments.
The default constructor's job is to call the super class constructor and initialize all instance variables. If the super class constructor is not present then it automatically initializes the instance variables to zero. So, that serves the purpose of using constructor, which is to initialize the internal state of an object so that the code creating an instance will have a fully initialized, usable object.
Once we define our own constructor for the class, the default constructor is no longer used. So, neither of them is actually a default constructor.
When you don’t define any constructor in your class, compiler defines default one for you, however when you declare any constructor (in your example you have already defined a parameterized constructor), compiler doesn’t do it for you.
Since you have defined a constructor in class code, compiler didn’t create default one. While creating object you are invoking default one, which doesn’t exist in class code. Then the code gives an compilation error.
When you create a new Module object, java compiler add a default constructor for you because there is no constructor at all.
class Module{} // you will never see the default constructor
If you add any kind of constructor even and non-arg one, than java thing you have your own and don't add a default constructor anymore.
This is an non-arg constructor that internelly call the super() constructor from his parent class even you don't have one. (if your class don't have a parent class than Object.Class constructor will be call)
class Module{
Module() {} // this look like a default constructor but in not.
}
A default constructor does not take any arguments:
public class Student {
// default constructor
public Student() {
}
}
I hope you got your answer regarding which is default constructor.
But I am giving below statements to correct the comments given.
Java does not initialize any local variable to any default value. So
if you are creating an Object of a class it will call default
constructor and provide default values to Object.
Default constructor provides the default values to the object like 0,
null etc. depending on the type.
Please refer below link for more details.
https://www.javatpoint.com/constructor
I have the following code but I don't get why when I run this it prints "b" before printing "h hn x". Why does "b" get printed at all since I am not calling the superclass Building at all when I execute House().
class Building {
Building() {
System.out.print("b ");
}
Building(String name) {
this();
System.out.println("bn " + name);
}
}
public class House extends Building {
House() {
System.out.println("h ");
}
House(String name) {
this();
System.out.println("hn " + name);
}
public static void main(String[] args) {
new House("x ");
}
}
The zero-arg constructor of a superclass is implicitly called by the constructor of its subclass, automatically.
More generally, for
class B extends A
The constructor
public B()
{
//Your code
}
Actually looks like
public B()
{
super(); //Call the superclass constructor
//Your code
}
You can override this behavior by making an explicit call to some other superclass constructor. Note that if the implicit call to the constructor cannot be made (like if your no-arg constructor doesn't exist), then you will see an error.
The superclass constructor is always called whenever a subclass is being constructed. If the superclass constructor does not require any arguments, as is the case here, this call can be made implicitly.
If you were to introduce an argument in the constructor for Building, you'd get an error in House as it will require you to explicitly call the new superclass constructor.
Official resource:
From the Oracle javase tutoriel:
With super(), the superclass no-argument constructor is called. With
super(parameter list), the superclass constructor with a matching
parameter list is called. Note: 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.
If a subclass constructor invokes a constructor of its superclass,
either explicitly or implicitly, you might think that there will be a
whole chain of constructors called, all the way back to the
constructor of Object. In fact, this is the case. It is called
constructor chaining, and you need to be aware of it when there is a
long line of class descent.
Additional resource:
The section Constructor Chaining From the SCJP 6 book explains clearly what you are looking for with in a simple manner, it provides also a little more informations about this process:
We know that constructors are invoked at runtime when you say new on
some class type as follows: Horse h = new Horse(); But what really
happens when you say new Horse() ? (Assume Horse extends Animal and
Animal extends Object.)
Horse constructor is invoked. Every constructor invokes the constructor of its superclass with an (implicit) call to super(),
unless the constructor invokes an overloaded constructor of the same
class (more on that in a minute).
Animal constructor is invoked (Animal is the superclass of Horse).
Object constructor is invoked (Object is the ultimate superclass of all classes, so class Animal extends Object even though you don't
actually type "extends Object" into the Animal class declaration. It's
implicit.) At this point we're on the top of the stack.
Object instance variables are given their explicit values. By explicit values, we mean values that are assigned at the time the
variables are declared, like "int x = 27", where "27" is the explicit
value (as opposed to the default value) of the instance variable.
Object constructor completes.
Animal instance variables are given their explicit values (if any).
Animal constructor completes.
Horse instance variables are given their explicit values (if any).
Horse constructor completes.
Analogy with your example:
So when you said new House("x "), here is what happens:
The House(String name) invokes House() as specified by the keyword this().
The House() constructor implicitly calls super() which invoks the construcotr Building().
The Building() constructor implicitly calls super() which is the Object constructor.
The Object constructor completes
The Building() constructor will complete and print "b "
The House() constructor will complete and print "h"
The House(String name) constructor will complete and print "hn x ".
The result is "b h hn x "
NB: Building(String name) would be invoked if you added an explicit call from House() to super("someString"), in that case the result will be: "b bn someString h hn x "
In inheritance it is necessary to initialize all the fields present in super-class first, because those fields are get used in subclasses, for this before construction of your subclass super class constructor get called to initialize all the field present in your super class.
Super class constructor called when you construct subclass instance. In your code you are creating new House("x "); Instance of House.
It calls House parametrized constructor House(String name) at this time your super class implicit constructor get called.
If you step through program the call stack shows what's happing:
(you need to follow the call stack from bottom to top):
House(Building).<init>() line: 3
House.<init>() line: 2
House.<init>(String) line: 7
House.main(String[]) line: 12
First Main is called
Then in the House(name) constructor this() is called
This calls the House() constructor (because no argument is provided)
Now comes the interesting part: because the Default constructor is called and House is derived from Building, it is required to construct the Building first which by specification is the default constructor of the parent class Building.
I have some java Code:
class Protected{
int n = 1;
public Protected(){
System.out.println("Constructor of protected");
System.out.println("========================");
System.out.println("n = "+n);
System.out.println();
}
}
class Derived extends Protected{
Derived(){
System.out.println("Constructor of derived");
System.out.println("======================");
System.out.println("n = "+(n+1));
}
}
public class Demo{
public static void main(String args[]){
Derived ob2 = new Derived();
}
}
I got the output as:
constructor of protected
========================
n=1
constructor of Derived
========================
n=2
This is what I want:
constructor of Derived
========================
n=2
A superclass constructor must be called for every new instance of a subclass. If you don't supply an explicit call to a superclass constructor in your subclass constructor, then Java will insert an implicit call to the no-argument superclass constructor. This explains why you see the output of your superclass constructor.
To remove that output, you can do one of the following:
1) Remove the output statements from the superclass constructor.
2) Create another constructor in the superclass that doesn't output anything, and explicitly call it in the subclass constructor.
Section 8.8.7 of the JLS states:
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 implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
This is what is happening implicitly:
class Derived extends Protected{
Derived(){
super(); // <--- This is called whether you want to or not
System.out.println("Constructor of derived");
System.out.println("======================");
System.out.println("n = "+(n+1));
}
There is absolutely no way to do this in Java; it would break the language specification. Don't put a print statement in the base class if the printing is not desired.
JLS 12 Execution / 12.5 Creation of New Class Instances
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor [...]
If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then [...]
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super).
Execute the instance initializers and instance variable initializers for this class [...]
Execute the rest of the body of this constructor [...]
You should not extend the super class to get the desired output. Or You can define another overloaded Constructor in Super class and, you need to call it explicitly in sub class Constructor.
When a sub class Constructor invoked, before the constructor's body get executed, Super class Constructor will be called, Hence the output of you program.
In the code below, the output is : S1S2. Why do we get the that result?
public class S1 {
public static void main(String[] args) {
new S2();
}
S1(){
System.out.print("S1");
}
}
class S2 extends S1{
S2(){
System.out.print("S2");
}
}
Since S2 extends S1, it's equivalent to calling all the constructors in a top-level down order.
Java will first create the parent object, S1 and call it's constructor. Then move down to the next object, S2 with it's constructor.
If a derived class's constructor doesn't explicitly call its base class's constructor (via super(...)) then there is an implicit call
super();
to the base class's default constructor in each derived class's constructor.
In the constructor of a subclass, there is an implicit call to the superclass's default constructor.
Here is a quote from the 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 superclass constructor
invocation "super();", an invocation of the constructor of its direct
superclass that takes no arguments.
I am making some revisions from the lecture slides and it says a constructor is executed in the following way:
If the constructor starts with this, recursively execute the indicated constructor, then go to step 4.
Invoke the explicitly or implicitly indicated superclass constructor (unless this class is java.lang.Object).
Initialise the fields of the object in the order in which they were declared in this class.
Execute the rest of the body of this constructor.
What I don't understand is that a constructor can never "start" with this, because even if it forms no class hierarchy/relationship then super() is inserted by default.
How would this fit in with the description above?
A constructor (for every class except java.lang.Object) has to start with either "super()", to call its superclass' constructor, or "this()", to call another constructor of the same class. If you don't include either of those in your constructor the compiler will insert a call to super(). It's fine for a constructor to start with a call to another constructor in the same class, as long as eventually a constructor in the class gets called that calls a superclass constructor.
I don't think you're right, or I don't understand the problem. From the Java 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 superclass
constructor invocation "super();", an
invocation of the constructor of its
direct superclass that takes no
arguments.
As such a constructor can start with this(...) which calls another constructor of the same class. Only when a constructor is called which does not start with either this(...) or super(...), super() is called automatically.
What I would say is that after an object is constructed super(...) has been called (if the class is not java.lang.Object).
here a more or less practical example for using this(...)
public class Car {
private final int numberOfDoors;
public Car(int doors) {
numberOfDoors = doors;
}
public Car() {
this(4); // default is 4 doors, calls the constructor above
}
}
the first statement in constructor body should be this or super , if nothing is there compiler by defalt keeps a super() keyword (with no argument).
so the Constructor body executes in this way:
Execution will happen on the basis of this or super keyword, then
it will execute all IIB's (as top down approach), then
it will execute all the statments kept by the programmer (like sop, initilization)
Class A{
A() {
this(10); //or super,....... execution statement 1
// executing IIB's, execution statement 2
System.out.println("from A()"); // execution statement 3
}
A(int i) {
System.out.println("from A(int)");
}
{
System.out.println("from IIB-1");
}
public static void main(String[] args){
A a = new A(); //calling constructor A()
System.out.println("from main");
}
{
System.out.println("from IIB-2");
}
}
Output:
from IIB-1
from IIB-2
from A(int)
from A()
from main
In Java, when you instantiate any object with new like C c = new C(); it delegate its super class constructor to create it first.
So in your case new C() --> Delegates to --> B() --> Delegates to A()
So execution flow is as below:
1) A() will Prints : 2
2) B() will calls B(1 ) prints 3 and control return to B() constructor
3) B() will prints : 4
4) C() will prints : 6
I hope it is now clear