What will be the type of the object in the constructor chain?

Why does this code only return the C class name. When I use this, it should return the constructor class name from which I am using it.

class A{
     public A() {
         System.out.println(this.getClass().getName());
     }
}
class B extends A{
    public B() {
        System.out.println(this.getClass().getName());
    }
}
class C extends B{
     public C() {
         System.out.println(this.getClass().getName());
     }
}
class Main{
    public static void main(String[] args){
         new C();
    }
}

      

+3


source to share


3 answers


First of all, when calling new Child (), since there is no declared no-argument constructor in Child class, it would be a simple call to super (), which calls the parent's constructor.



Then, when doing this.getClass (). getName (), here it means a Child instance, so you get "Child" as the result. Remember that object # getClass () returns the most specific class to which the object belongs. see details here .

0




this.getClass().getName()

returns the name of the instance's execution type this

. If you instantiate C ( new C()

), it will always return "packagename.C". It doesn't matter if you call it from class code C

or from code in superclasses C

.



+4


source


Some related points:

1) The compiler will automatically insert a superclass constructor call no argument into any constructor that does not contain an explicit superclass constructor call. (I recommend that you choose explicit behavior over implicit behavior when writing code, but this is a moot point in style.) Anyway, to the compiler, your code will look like this:

class A{
    public A() {
        System.out.println(this.getClass().getName());
    }
}

class B extends A{
    public B() {
        super();
        System.out.println(this.getClass().getName());
    }
}

class C extends B{
    public C() {
        super();
        System.out.println(this.getClass().getName());
    }
}

class Main{
    public static void main(String[] args){
        new C();
    }
}

      

This makes it clear that System.out.println is called three times.

2) Using this inside a constructor to call methods can lead to rather strange behavior in general. See for example: this . This is because initialization works like this:

1) The constructor of class C is called. At this moment, memory is allocated for an object of class C, and the metadata of objects, including its class, the implemented interfaces are filled inside the virtual machine. All fields, including inherited fields, are initialized with a default value.

2) The constructor of class B is called. Inside the constructor, it refers to an object of class C, but none of the fields initialized in the constructor of C have yet been initialized. This will immediately call the constructor of class A.

3) The constructor of class A is executed. The fields specified in this constructor are initialized. The constructor does the methods and initializes and returns and the stack goes back to the constructor B.

4) Constructor B executes its methods and returns control to constructor C.

5) The C constructor returns.

So now we understand what's going on: This rung prints C three times. I suspect you want to write:

    class A{
    public A() {
        System.out.println(A.class.getName());
    }
}

class B extends A{
    public B() {
        super();
        System.out.println(B.class.getName());
    }
}

class C extends B{
    public C() {
        super();
        System.out.println(C.class.getName());
    }
}

class Main{
    public static void main(String[] args){
        new C();
    }
}

      

which will print A, B, C.

+1


source







All Articles