Init'ing fields

  • Thread starter James D Carroll
  • Start date
J

James D Carroll

I've code of both varieties below:

public class foo {
someClass sc;

public foo (){
sc = new someClass(): //init member in ctor
}
}

** versus **

public class foo() {
someClass sc = new someClass; /init member outside ctor

public foo(){
}
}

Is there any real difference between the two?


Thanks,
 
T

Tom Dyess

Yes and no, the latter is a shortcut to the former. It DOES run the
constructor code before the inline declaration/creation objects definitions
though. Some consider this bac practice because you are having objects
constructed outside the constructor. I do it though, but I do have to be
mindful of them when otherwise, I would just have to be mindful of the
constructor.
 
T

Tony Morris

James D Carroll said:
I've code of both varieties below:

public class foo {
someClass sc;

public foo (){
sc = new someClass(): //init member in ctor
}
}

** versus **

public class foo() {
someClass sc = new someClass; /init member outside ctor

public foo(){
}
}

Is there any real difference between the two?


Thanks,

Yes there is a difference.
Some consider the latter poor form, but only to avoid the consequences of
writing code that is truly poor, specifically, when you call an overridable
method on a this (implicit or not) reference from a constructor, there may
some side effect and you should *NEVER* do that.

Here's an example:
http://www.xdweb.net/~dibblego/java/trivia/answers.html#q4
 
R

Ryan Stewart

Tony Morris said:
Some consider the latter poor form, but only to avoid the consequences of
writing code that is truly poor, specifically, when you call an
overridable
method on a this (implicit or not) reference from a constructor, there may
some side effect and you should *NEVER* do that.
I thought we had this discussion here already. "Never" is a strong word.
You should really use clearer terms on this site. Wouldn't you consider an
object to be created when memory is allocated for it and its members are
initialized? Besides which, initialization is a part of object instantiation
(two parts, actually). The two are not separate processes.
 
E

epicwinter

I have run into problems using the latter when subclassing, because of
the execution order.
 
T

Tony Morris

Ryan Stewart said:
I thought we had this discussion here already. "Never" is a strong word.

We did?
I meant to use a strong word. It should never occur.
Some programming languages go on to prevent it at compile-time.
Java unfortunately, doesn't.
You should really use clearer terms on this site. Wouldn't you consider an
object to be created when memory is allocated for it and its members are
initialized? Besides which, initialization is a part of object instantiation
(two parts, actually). The two are not separate processes.

I used the terminology from the Java Language Specification Second Edition
when I wrote it.
 
J

John C. Bollinger

Tom said:
Yes and no, the latter is a shortcut to the former. It DOES run the
constructor code before the inline declaration/creation objects definitions
though.

Careful. Variable initializers and instance initializers are run after
the *superclass'* constructor but before the (rest of) the constructor
body for the class in which they appear. This is as specified in
JLS(2e) 8.8.6. It is easy to write a test class that demonstrates this
behavior:


public class InitOrder {
int initWithInitializer = 42;
int initInConstructor;

public InitOrder() {
/*
* Implicit invocation of Object() occurs here
*
* The instance variable initializer then runs before the
* (rest of) the constructor body.
*/

System.out.println("At constructor start:");
System.out.println(" initWithInitializer = "
+ initWithInitializer);
System.out.println(" initInConstructor = "
+ initInConstructor);

/*
* The last println() above shows initInConstructor with its
* default value
*/

initInConstructor = 17;

System.out.println("At constructor end:");
System.out.println(" initWithInitializer = "
+ initWithInitializer);
System.out.println(" initInConstructor = "
+ initInConstructor);
}

public static void main(String[] args) {
InitOrder instance = new InitOrder();

System.out.println("After constructor:");
System.out.println(" initWithInitializer = "
+ instance.initWithInitializer);
System.out.println(" initInConstructor = "
+ instance.initInConstructor);
}
}


====

D:\temp\testdir>java -cp . InitOrder
At constructor start:
initWithInitializer = 42
initInConstructor = 0
At constructor end:
initWithInitializer = 42
initInConstructor = 17
After constructor:
initWithInitializer = 42
initInConstructor = 17

====


John Bollinger
(e-mail address removed)
 
C

Chris Smith

Tony Morris said:
Yes there is a difference.
Some consider the latter poor form, but only to avoid the consequences of
writing code that is truly poor, specifically, when you call an overridable
method on a this (implicit or not) reference from a constructor, there may
some side effect and you should *NEVER* do that.

How is this relevant to calling such a method from a superclass
constructor? In either of the code samples given, the field would not
have been initialized yet when the method is called.

That's an example of something, but I'd like to hear how you think it's
relevant to this thread. I might be missing something here.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Ryan Stewart

Tony Morris said:
I meant to use a strong word. It should never occur.
Never say never.
Some programming languages go on to prevent it at compile-time.
Java unfortunately, doesn't.
Personally, I'm glad to be using a language that doesn't tell me I can't do
something just because I might not understand what I'm doing.
I used the terminology from the Java Language Specification Second Edition
when I wrote it.
Java Language Specification 2.0 §12.5:
"Whenever a new class instance is created, memory space is allocated for
it..."
1) Class instantiation/object creation begins

"[and] all the instance variables in the new object, including those
declared in superclasses, are initialized to their default values."
2) First initialization process

"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..."
3) Second initialization process and end of class instantiation/object
creation
 
T

Tom Dyess

Whoops. Good eye.

John C. Bollinger said:
Tom said:
Yes and no, the latter is a shortcut to the former. It DOES run the
constructor code before the inline declaration/creation objects
definitions though.

Careful. Variable initializers and instance initializers are run after
the *superclass'* constructor but before the (rest of) the constructor
body for the class in which they appear. This is as specified in JLS(2e)
8.8.6. It is easy to write a test class that demonstrates this behavior:


public class InitOrder {
int initWithInitializer = 42;
int initInConstructor;

public InitOrder() {
/*
* Implicit invocation of Object() occurs here
*
* The instance variable initializer then runs before the
* (rest of) the constructor body.
*/

System.out.println("At constructor start:");
System.out.println(" initWithInitializer = "
+ initWithInitializer);
System.out.println(" initInConstructor = "
+ initInConstructor);

/*
* The last println() above shows initInConstructor with its
* default value
*/

initInConstructor = 17;

System.out.println("At constructor end:");
System.out.println(" initWithInitializer = "
+ initWithInitializer);
System.out.println(" initInConstructor = "
+ initInConstructor);
}

public static void main(String[] args) {
InitOrder instance = new InitOrder();

System.out.println("After constructor:");
System.out.println(" initWithInitializer = "
+ instance.initWithInitializer);
System.out.println(" initInConstructor = "
+ instance.initInConstructor);
}
}


====

D:\temp\testdir>java -cp . InitOrder
At constructor start:
initWithInitializer = 42
initInConstructor = 0
At constructor end:
initWithInitializer = 42
initInConstructor = 17
After constructor:
initWithInitializer = 42
initInConstructor = 17

====


John Bollinger
(e-mail address removed)
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top