the JVM and super

C

conrad

My book does not tell me this but when you
create a subclass of a class that contains,
as an example, private data members:
private String firstName;
private String lastName;

Then an instance of your subclass will
contain those members and to initialize
them you must invoke super to call
the class's constructor. This is
because constructors are not inherited
by a subclass.

Now my question: How does the
JVM /typically/ handle this?
I'll make clear what I mean by "this."
Let's call the two types: A
and B where B extends A.
When one creates B via the
new operator, the constructor of
B is invoked, and whether explicitly
or implicitly, super is included
as the first method invocation
in B. But if A's constructor is
not inherited by B, and A's constructor
modifies the private data members
inherited by B, does this mean
the call to super acts as a static
method of sorts in this context?

Could someone elaborate on this
and the correct way to think about
it?
 
A

Arne Vajhøj

conrad said:
My book does not tell me this but when you
create a subclass of a class that contains,
as an example, private data members:
private String firstName;
private String lastName;

Then an instance of your subclass will
contain those members and to initialize
them you must invoke super to call
the class's constructor. This is
because constructors are not inherited
by a subclass.

Now my question: How does the
JVM /typically/ handle this?
I'll make clear what I mean by "this."
Let's call the two types: A
and B where B extends A.
When one creates B via the
new operator, the constructor of
B is invoked, and whether explicitly
or implicitly, super is included
as the first method invocation
in B. But if A's constructor is
not inherited by B, and A's constructor
modifies the private data members
inherited by B, does this mean
the call to super acts as a static
method of sorts in this context?

Could someone elaborate on this
and the correct way to think about
it?

You descriptions sounds correct.

But it has nothing to with static since
it is all instance stuff.

Arne
 
C

conrad

You descriptions sounds correct.

But it has nothing to with static since
it is all instance stuff.

Arne

Well, think about this:
B calls a constructor that
is not a part of B, and the constructor
modifies members contained in B.

So the instance of B relies on
a special kind of method(a
constructor) that is not
contained in B. Of course,
this isn't /exactly/ like
a static method but the
behavior is similar it would seem.
 
A

Arne Vajhøj

conrad said:
Well, think about this:
B calls a constructor that
is not a part of B, and the constructor
modifies members contained in B.

So the instance of B relies on
a special kind of method(a
constructor) that is not
contained in B. Of course,
this isn't /exactly/ like
a static method but the
behavior is similar it would seem.

No.

I think where it goes wrong is the "B calls a constructor
that is not a part of B".

The constructors of A are part of B. They are just not
constructors for B.

The code is there and are very much tied to the instance.

Arne
 
J

Joshua Cranmer

conrad said:
Now my question: How does the JVM /typically/ handle this? I'll make
clear what I mean by "this." Let's call the two types: A and B where
B extends A. When one creates B via the new operator, the constructor
of B is invoked, and whether explicitly or implicitly, super is
included as the first method invocation in B. But if A's constructor
is not inherited by B, and A's constructor modifies the private data
members inherited by B, does this mean the call to super acts as a
static method of sorts in this context?

A call to |new B()| will construct this bytecode:
new B
dup
invokespecial B:<init>()V [1]

Inside B's constructor, the call |super()| (whether implied or not) is
the same as this:
invokespecial A:<init>()V

The thing to note about the bytecode is that it is not calling super via
an invokevirtual call, so it does not follow polymorphic rules for
finding the actual method to call. Other cases where non-virtual calls
are used are when calling super.<method name> or calling a private method.

In short: it's not a static method of sorts, it's a call that suppresses
polymorphic effects.

[1] Two things to point out about this instruction. The first is that
invokespecial is one of four (five, if you include the
unusable-from-Java invokedynamic) invocation instructions:
invokespecial, invokeinterface, invokevirtual, and invokestatic.
invokespecial used to be called, in the first edition of the JVM spec,
invokenonvirtual, which should be a bit more explanatory about its effects.

The second thing to point out is that the constructor is a special
method called <init> with a void return.
 
T

Tom Anderson

Well, think about this: B calls a constructor that is not a part of B,
and the constructor modifies members contained in B.

The constructor *is* part of B.

Kind of.

It's not really the case that constructors aren't inherited - it's just
that a constructor inherited by a subclass isn't a constructor for that
subclass. It's still a constructor for the superclass.

Think of a constructor for a type T as being a method which returns an
instance of T. If you make a class S which extends T, then inherits any
constructors - but they're still constructors for T, not S!

tom
 
L

Lew

From a Java language standpoint, a constructor is not a method.

As others have explained, that is not what it means. Think about it - how
could a static invocation possibly affect instance members?

Read the Java Language Specification (JLS) for the intimate details:
<http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.5>

Tom said:
It's not really the case that constructors aren't inherited

Actually, it is really the case that constructors aren't inherited.

JLS s. 6.4.3:
Members are either declared in the type,
or inherited because they are accessible members
of a superclass or superinterface which are neither
private nor hidden nor overridden (§8.4.8). ....
Constructors (§8.8) and type variables (§4.4) are not members.

JLS s. 8.8
 
M

Mark Space

conrad said:
Now my question: How does the
JVM /typically/ handle this?

As Joshua said, I don't think the JVM handles this. I think the
compiler does. In other words, when a constructor gets invoked, there
had better be calls actually in the byte code to call the super class's
constructor, or the constructor won't get called.
I'll make clear what I mean by "this."
Let's call the two types: A
and B where B extends A.
When one creates B via the
new operator, the constructor of
B is invoked, and whether explicitly
or implicitly, super is included
as the first method invocation
in B. But if A's constructor is
not inherited by B, and A's constructor
modifies the private data members
inherited by B, does this mean

This is I think where you are messing up. There private members are not
inherited by B. They are there, but not as part of B. They are part of
A, and can be accessed by A. Remember, private doesn't inherit, public
and protected do, and sometimes package-private. But it's there and
accessible.
the call to super acts as a static
method of sorts in this context?

Not really, there's a this-reference associated with the constructor,
unlike static methods. Constructors just aren't inherited, that's all.
Could someone elaborate on this
and the correct way to think about
it?

The only bit of advice I can think of is that all of A's members (fields
and methods) are present and accessible by A, even if they are
restricted (private) access from B. They may not be inherited, but
they're there and A can access them.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top