State of 'this' in constructor body

M

Matthias Kaeppler

Hello,

I have decent knowledge of the C++ programming language, and I am
currently reading a book about Java ("Java in a Nutshell", 5th Edition,
O'Reilly).

I have a question concerning the construction of objects in Java. In
C++, the this-pointer is valid to use in the constructor body, because
C++ makes sure that when the ctor body is entered, the object has been
fully initialized to a default state, as defined by the constructor's
initializer list. This is a /good/ thing, because you are able to
provide your own initializer list, and may keep the compiler from
default-constructing a data member which value you would have hanged
anyway in the constructor (otherwise the object would have been
initialized twice, which is just brainless overhead and especially
expensive for complex user defined types).
Since Java does not have initializer lists, I can't imagine how this works:

public class Bar {

public Bar() {
this.a = 5; // which object does 'this' reference, when I
// am still in the state of initializing it?
}

}

I can only guess that the JVM takes care of default initializing each
data member before entering the constructor body, otherwise the
this-reference would reference an object which doesn't have a
well-defined state (and would probably lead to undefined behavior).

Is this true, and if this is the case, doesn't this imply a performance
hit to initialize every data member twice (in the worst case)?

Thanks in advance.
 
T

Tor Iver Wilhelmsen

Matthias Kaeppler said:
public class Bar {

public Bar() {
this.a = 5; // which object does 'this' reference, when I
// am still in the state of initializing it?
}

No, the object is constructed: You are now initializing it. The
constructor is synthesized into a specially treated void instance
method.
I can only guess that the JVM takes care of default initializing each
data member before entering the constructor body,

It does.
Is this true, and if this is the case, doesn't this imply a
performance hit to initialize every data member twice (in the worst
case)?

No, because the default initialization to 0/0.0/null is done very
rapidly by the "new" keyword execution.
 
M

Matthias Kaeppler

Tor said:
No, the object is constructed: You are now initializing it. The
constructor is synthesized into a specially treated void instance
method.




It does.




No, because the default initialization to 0/0.0/null is done very
rapidly by the "new" keyword execution.

Okay, thanks Tor.
 
M

Matthias Kaeppler

Tor said:
No, the object is constructed: You are now initializing it. The
constructor is synthesized into a specially treated void instance
method.




It does.




No, because the default initialization to 0/0.0/null is done very
rapidly by the "new" keyword execution.

On a second thought, this raises the question:

Does it make sense at all to explicitly initialize data members with
0/0.0/null? I suppose if you do, it's optimized away by the runtime
anyway (since you said, the runtime does this implicitly anyway before
entering the ctor body).

e.g.:

public class Bar {

public Bar() {
foo_ = null; // this is superfluous, right?
// (given that foo_ is considered to be
// constructed later in program execution)
}

Foo foo_;

}

I once heard that it'd be considered good style to do that, but after
what you've said, it's just right out useless, ain't it?
 
K

Kevin McMurtrie

Matthias Kaeppler said:
On a second thought, this raises the question:

Does it make sense at all to explicitly initialize data members with
0/0.0/null? I suppose if you do, it's optimized away by the runtime
anyway (since you said, the runtime does this implicitly anyway before
entering the ctor body).

e.g.:

public class Bar {

public Bar() {
foo_ = null; // this is superfluous, right?
// (given that foo_ is considered to be
// constructed later in program execution)
}

Foo foo_;

}

I once heard that it'd be considered good style to do that, but after
what you've said, it's just right out useless, ain't it?

You can also declare field values along with the type.

Foo m_foo= null;

This gets run by the <init> routine right before the constructor is
executed. They should be fairly simple values because <init> is tricky
to debug.
 
A

Andrew McDonagh

Matthias said:
Hello,

I have decent knowledge of the C++ programming language, and I am
currently reading a book about Java ("Java in a Nutshell", 5th Edition,
O'Reilly).

I have a question concerning the construction of objects in Java. In
C++, the this-pointer is valid to use in the constructor body, because
C++ makes sure that when the ctor body is entered, the object has been
fully initialized to a default state, as defined by the constructor's
initializer list. This is a /good/ thing, because you are able to
provide your own initializer list, and may keep the compiler from
default-constructing a data member which value you would have hanged
anyway in the constructor (otherwise the object would have been
initialized twice, which is just brainless overhead and especially
expensive for complex user defined types).
Since Java does not have initializer lists, I can't imagine how this works:

public class Bar {

public Bar() {
this.a = 5; // which object does 'this' reference, when I
// am still in the state of initializing it?
}

}

The reason for initializer lists in C++ is due to c++ refs always having
to be initialised to refer to some object. However, Java does not have
these types of references - Javas can either point to nothing (i.e.
NULL) or to any object of the same or derived type of the reference.

Therefore, because Java refs can legally point to null, we don't need
initializer lists. Also, because Java refs can point to null, member
var references that are not explicitly initialised are automatically
initialised to point to NULL, so no default constructors are called.

e.g.

class Foo {
private String aString; // auto assigned to NULL;
private String string2 = null; // legal but not needed.
}
I can only guess that the JVM takes care of default initializing each
data member before entering the constructor body, otherwise the
this-reference would reference an object which doesn't have a
well-defined state (and would probably lead to undefined behavior).

Is this true, and if this is the case, doesn't this imply a performance
hit to initialize every data member twice (in the worst case)?

Thanks in advance.

If you have a debugger in your IDE, it would be worth putting a
breakpoint on the constructor and stepping into it, in order to help you
understand how objects are created in Java.

To get the best out of this simple technique - you'd want to use a
mixture of primitives and objects members, some of which are initialised
and some that aren't.

e.g.



public class Bar {

public Bar() { // Put break point here!

// nice little test here...lets use one member to init another..
this.a = secondIntObj.intValue();

// what value will firstIntObj ref to here?
firstIntObj = new Integer(a);
}

private int a;
private int a2 = 1;
private Integer firstIntObj;
private Integer secondIntObj = new Integer(2);
}
 
J

Johan Poppe

Matthias said:
Does it make sense at all to explicitly initialize data members with
0/0.0/null? I suppose if you do, it's optimized away by the runtime
anyway (since you said, the runtime does this implicitly anyway before
entering the ctor body).

e.g.:

public class Bar {

public Bar() {
foo_ = null; // this is superfluous, right?
// (given that foo_ is considered to be
// constructed later in program execution)
}

Foo foo_;

}

I once heard that it'd be considered good style to do that, but after
what you've said, it's just right out useless, ain't it?

Most of the things that are "considered good style" have nothing to do
with how the program runs, but with how the code is read by humans. As
with this thing. It's superfluous and useless in terms of impact on
the result of the program, but it might be considered good style in
terms of the programmer declaring to anyone reading the code later
that "The foo_ variable is not properly initialized in the
constructor, it's still null when the constructor has finished, and
I'm aware of that and it's intended and bla bla bla."

I do this myself sometimes, but far from always. Which I guess is
really bad style.
 
?

=?iso-8859-1?q?Markus_B._Kr=FCger?=

Andrew McDonagh said:
The reason for initializer lists in C++ is due to c++ refs always
having to be initialised to refer to some object.

Another reason is that C++ objects may have member variables that
aren't refs, but are objects of a class with no default constructor
(that is to say, no public constructor with no arguments). The
enclosing object's constructor therefore needs some way to provide
argument values for the members' constructors, since the members are
initialized before the main body of the enclosing object's constructor
is entered. As you wrote, Java does not need this, since all member
variables in Java are references initialized to null.
 

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
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top