Does the JVM internally instantiate an object for

2020-06-24 06:21发布

问题:

I have an abstract class and its concrete subclass, when I create an object of subclass it automatically calls the super constructor. Is the JVM internally creating an object of the abstract class?

public abstract class MyAbstractClass {

    public MyAbstractClass() {
        System.out.println("abstract default constructor");
    }

}
public class ConcreteClass extends MyAbstractClass{

    public static void main(String[] args) {
        new ConcreteClass();
    }

}

then how constructor exists without an object in JVM ?? (In case of abstract class)

Also constructor gets executed after object is being created then without creating the object of abstract class how the default constructor get executed ?? (This is mentioned in Java Doc)

回答1:

Is it true that you can't instantiate abstract class?

Yes.

Is JVM internally create object of abstract class ?

No, but it's a common misunderstanding (and that wouldn't be an unreasonable way for it to be done; prototypical languages like JavaScript do it that way).

The JVM creates one object, which is of the class you created (in your case, ConcreteClass). There are aspects of that one object that it gets from its superclass (MyAbstractClass) and from its subclass (ConcreteClass), but there is only one object.

The object is an aggregate of all of its parts, including parts that seem to have the same name, such as a method of the superclass that is overridden by the subclass. In fact, those methods have different fully-qualified names and don't conflict with one another, which is why it's possible to call the superclass's version of an overridden method.

So if it's just one object, why do you see the call to MyAbstractClass's constructor? Before we answer that, I need to mention a couple of things the Java compiler is doing that you don't see in the source code:

  1. It's creating a default constructor for ConcreteClass.

  2. In that constructor, it's calling the MyAbstractClass constructor.

  3. Just to be thorough: In the MyAbstractClass constructor, it's adding a call to the superclass's (Object) constructor, because there's no super(...) call written within the MyAbstractClass constructor.

Here's what the code looks like with the bits the Java compiler adds for you filled in:

public abstract class MyAbstractClass {

    public MyAbstractClass() {
        super();           // <== The Java compiler adds this call to Object's constructor (#3 in the list above)
        System.out.println("abstract default constructor");
    }

}
public class ConcreteClass extends MyAbstractClass{

    ConcreteClass() {      // <== The Java compiler adds this default constuctor (#1 in the list above)
        super();           // <== Which calls the superclass's (MyAbstractClass's) constructor (#2 in the list above)
    }

    public static void main(String[] args) {
        new ConcreteClass();
    }

}

Okay, with that out of the way, lets touch on a point TheLostMind very usefully mentioned in a comment: Constructors don't create objects, they initialize them. The JVM creates the object, and then runs as many constructors (they really should be called initializers) against that one object as necessary to give each superclass a chance to initialize its part of the object.

So in that code, what happens (and you can step through this in a debugger to fully understand it) is:

  1. The JVM creates an object

  2. The ConcreteClass constructor is called

    1. The first thing that constructor does is call its superclass's constructor, in this case MyAbstractClass's constructor. (Note that this is an absolute requirement: The Java compiler will not allow you to have any logic in the constructor itself prior to the superclass constructor call.)

      1. The first thing that constructor does is call its superclass's constructor (Object's)

      2. When the Object constructor returns, the remainder of the MyAbstractClass constructor runs

    2. When the MyAbtractClass constructor returns, the remainder of the ConcreteClass constructor runs

  3. The object is returned as the result of the new ConcreteClass() expression.

Note that the above would get more complicated if there were instance fields with initializers. See the JLS and JVM specs for the full details.



回答2:

JVM doesn't create object of abstract class. it is calling its super constructor



回答3:

JVM will create one object, an instance of the concrete class which inherits fields and methods of abstract class