3

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)

kavi temre
  • 1,321
  • 2
  • 14
  • 21
  • 3
    In the JVM there will only be one object and that would of type `ConcreteClass`. The call to `super class constructor` is necessary to add *super class features* to the child class. – TheLostMind May 08 '15 at 13:53
  • All instances of subclasses implicity call their superclass's constructor. You cannot instantiate an abstract class; only a subclass of it. You could instantiate it through an anonymous class, although it's not recommended – Vince May 08 '15 at 13:53
  • 2
    @VinceEmigh - *You could instantiate it through an anonymous class* - is not exactly *correct*. It would not be an instance of *abstract class*. The created instance would be an instance of *subclass of abstract class* – TheLostMind May 08 '15 at 13:55
  • @TheLostMind can you provide me some documentation about your logic "The call to super class constructor is necessary to add super class features to the child class". it is new to me and i think it is the correct explanation – kavi temre May 08 '15 at 13:59
  • i know that one cannot create object of abstract class . i am asking about JVM ?? – kavi temre May 08 '15 at 14:00
  • 1
    @TheLostMind That's pretty obvious.. I was just introducing a way of creating an instance without defining a new accessible type, for example, ConcreteClass. Sorry for not being 100% technical... – Vince May 08 '15 at 14:00
  • 1
    The JVM can't create an object whose class is an interface or an abstract class even if you hack the byte code or use `Unsafe`. – Peter Lawrey May 08 '15 at 14:03
  • @kavitemre - Create an abstract class and a concrete class that implements it.. put print statements in constructors for both classes and create an intsance of concrete class. See what will be printed – TheLostMind May 08 '15 at 14:06
  • @VinceEmigh - I know. But the OP should not be under the impression that *there is a way of creating instance of abstract class using anonymous classes* :) – TheLostMind May 08 '15 at 14:07
  • @TheLostMind . i have created the same, just see the question – kavi temre May 08 '15 at 14:15
  • @kavitemre - The constructor is an *object initializer* not an *object creator*. It is like a method which initializes *parent class values* in *child class instance*. The `new` keyword creates an instance and then the *constructor initializes it*. So, a constructor can exist without an *instance* – TheLostMind May 08 '15 at 14:18

3 Answers3

7

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.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Then what is significance of calling its constructor ? – java guy May 08 '15 at 13:55
  • 1
    @javaguy: Ensuring that logic required to initialize the base parts of the object is run. – T.J. Crowder May 08 '15 at 13:56
  • then how constructor exists without an object ?? (In case of abstract class) – kavi temre May 08 '15 at 14:17
  • 1
    @kavitemre: The `MyAbstractClass` constructor operates on the `ConcreteClass` object that was created; it's just that it can only see its part of that object, not the whole thing. – T.J. Crowder May 08 '15 at 14:19
  • @T.J.Crowder I know everything which you mentioned in your answer e.g. constructor calling and super().. My doubt is that How it possible that abstract class constructor exists without an object ?? – kavi temre May 08 '15 at 14:22
  • 1
    @kavitemre: Constructors and methods aren't part of the object, they're part of the class. Class = code, object = data. The code (the abstract constructor) operates on the data (the object). – T.J. Crowder May 08 '15 at 14:23
  • 1
    @kavitemre - The point which you are failing to see is - *a constructor only initializes objects, it doesn't create them*. – TheLostMind May 08 '15 at 14:24
  • @kavitemre: [JLS §12.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.5) seems on-topic. – T.J. Crowder May 08 '15 at 14:35
  • Hi T.J.Crowder , in above mention doc it is mentioned that " 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: " it means first object is created and then it execute its constructor before returning the object as a result. – kavi temre May 08 '15 at 14:55
  • @kavitemre: I glossed over a bit in the list at the end, which I've updated. I suggest re-reading the answer above beginning to end. **Don't** skip the parts you think you already know. – T.J. Crowder May 08 '15 at 15:08
  • so we can say that constructor are not part of an object. if i am setting a variable in abstract Class constructor than can we assume that those variable are not part of the object ??? – kavi temre May 08 '15 at 15:16
  • @kavitemre: Do you really mean **variable** (e.g., a local variable in the constructor), or do you mean **field** (a field on the object)? If the latter, then quoting from the answer: *"There are aspects of that one object that it gets from its superclass...and from its subclass"* The fields defined by the abstract class and initialized by its constructors are absolutely a part of the object. – T.J. Crowder May 08 '15 at 15:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77329/discussion-between-kavi-temre-and-t-j-crowder). – kavi temre May 08 '15 at 15:26
  • @kavitemre: No, I think I've gone as far down this road as I reasonably can. Good luck! – T.J. Crowder May 08 '15 at 15:30
  • public abstract class MyAbstractClass { int i; public MyAbstractClass() { System.out.println("abstract default constructor"); i = 0; } } is variable i is not a part of the object – kavi temre May 08 '15 at 15:32
  • @kavitemre: Again: *"There are aspects of that one object that it gets from its superclass...and from its subclass"* and *"The fields defined by the abstract class and initialized by its constructors are absolutely a part of the object."* **Yes**, `i` is part of the object. It's an instance field defined by `MyAbstractClass` and initialized by its constructor. – T.J. Crowder May 08 '15 at 15:34
3

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

java guy
  • 193
  • 3
1

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

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • what about constructor calling ?? it is true that when you call a constructor object gets created – kavi temre May 08 '15 at 13:56
  • @kavitemre - *it is true that when you call a constructor object gets created* - that depends on whether the class is *abstract* or *concrete*. Object gets created only for a *concrete* class. You cannot *explictly* use `new` to create an instance of an *abstract class* – TheLostMind May 08 '15 at 14:00
  • @TheLostMind - I know that one cannot create object of abstract class . i am asking about JVM ?? – kavi temre May 08 '15 at 14:01
  • No. The JVM won't create *instances* of *abstract* classes either. Note that the *class object* is created but not instance of abstract class – TheLostMind May 08 '15 at 14:08
  • @TheLostMind then how constructor exists without an object ?? (In case of abstract class) – kavi temre May 08 '15 at 14:19
  • @kavitemre - check my reply to your coment on the *question* – TheLostMind May 08 '15 at 14:20
  • JVM creates an empty object in heap with empty fields, concrete + abstract, both constructors are responsible for initializing its own class fields. – Evgeniy Dorofeev May 08 '15 at 14:22