• Post Reply Bookmark Topic Watch Topic
  • New Topic

Difference in variable assignment between Constructor and Variable section  RSS feed

 
Mario Schwaiger
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Given the case I have an object which is assigned only once.
What is the difference in doing:


and


Is there a difference in performance or usability? (Given also the case there are no static calls expected)

Thank you
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No difference in performance (of it there is it's not worth worrying about). Personally I find the first option easier to read so I'd use that in simple cases like the one you've given.

I'd use the second if:

- The initialisation depended on something passed into the constructor, or
- The initialisation was more complicated. For example if I need to create the object but then call some additional methods on it, or I needed to create it then pass it to another component. Then I'd want the creation and the use of the object to be in the same place.
 
Mario Schwaiger
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good to know...
Personally I prefer the fist one too, mostly because it's independent from the constructor (Given the case there are more constructors).

I thought of it more of a bad style to assign variables directly
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mario Schwaiger wrote:Personally I prefer the fist one too, mostly because it's independent from the constructor (Given the case there are more constructors).

OK. Let me play the devil's advocate here and say that I prefer the second.

Why? Because the first is misleading unless the field being assigned is a constant.

All it says is: this field starts out life as "Hello World"; but that has no bearing on what it might be when I actually use it. And for that sort of stuff, I prefer a constructor.

Also: A constructor is the ONLY way to initialise an instance-based constant (ie, a final field whose value is passed), because you can't assign a final field twice; therefore, you can't assign a value to it directly (you can if it isn't final - it just acts as a "default").

So: Why have two ways of doing things?

Winston
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is a good point Winston. I tend to mix which case I do, and I always hate it when I go back and read my code. I think I will try to move things to a constructor, generally, and see if I like that better. A counter point, which is what I usually think when I start to mix and match, is that if you know the initial value doesn't need to be delayed it seems easier to read the initial value when it is done in line, rather than provided elsewhere in the code.

But there is a bit from the OP which changes things:
Mario Schwaiger wrote:Given the case I have an object which is assigned only once.

If it is assigned just once, I would prefer to make it final and do the assignment in line:


Since then the intent is clear: This variable is assigned when the instance is made, has this value, and won't/can't be assigned a different value.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This presumes that myObj is intended to be a different instance for each instance of the surrounding class. If it is not necessarily a different instance, why not make it a proper constant and make it static?

I prefer the method with the constructor, too. I believe that you should write a constructor for every class you write, but after that you should write as few constructors as you can. The fewer constructors, the less risk there is of missing a field like that and forgetting to initialise it. Also the less scope there is for users of your class to initialise it in an inconsistent state.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote: A counter point, which is what I usually think when I start to mix and match, is that if you know the initial value doesn't need to be delayed it seems easier to read the initial value when it is done in line, rather than provided elsewhere in the code.

I certainly agree that eager instantiation is more "readable", but Campbell makes a valid point: if it is indeed a constant that you can assign directly, surely it ought to be static? If it isn't, then whatever you assign is simply a default.

Nothing wrong with defaults; although I tend to prefer the Builder pattern if I have lots of 'em.

I suppose eager initializtion might be reasonable when the target is a collection; particularly something like a LinkedList, which doesn't rely on any initial characteristics (like capacity).

Winston
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Making the field static is fine (and indeed preferable) if the object is immutable. If its not immutable then making it static may not be what you want. For example I probably wouldn't have a static List in my Class, even though it would almost always be final.

Personally I usually instantiate inline if the initial value is not passed in through a constructor (again, a List would be an example).

One thing that hasn't been mentioned here is Exceptions. If the objects constructor can throw a checked exception then you cannot instantiate it inline. You could use a non-static initialiser block I guess, but I cannot imagine why you would do that rather than use a constructor.
 
Mario Schwaiger
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
why not make it a proper constant and make it static?

Because it's not necessary - these variables are ~100% used within that class. Also doesn't change anything (http://stackoverflow.com/questions/3805155/are-java-static-calls-more-or-less-expensive-than-non-static-calls)


I prefer the method with the constructor, too.

What if different constructors with optional set of specific variables exist?

If it is assigned just once, I would prefer to make it final and do the assignment in line:

I forgot to mention that, you're right ;)
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mario Schwaiger wrote:

I prefer the method with the constructor, too.

What if different constructors with optional set of specific variables exist?



Isn't that one of the many things for which the builder pattern comes quite as a solace.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mario Schwaiger wrote: . . . What if different constructors with optional set of specific variables exist? . . .
You would have to assign it in each constructor. The this(…); construct would be helpful. I did say you should minimise the number of constructors written.

Find a copy of Effective Java™ by Joshua Bloch and find the chapter about using factory methods instead of public constructors. That is another way to construct objects.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

??? Of course it does. It changes the entire scope of the field.

With very few exceptions, an instance field initialized eagerly could just as easily be made static; otherwise, if it's final, its value will normally come from something passed to a constructor (indeed, it's basically how you create immutable objects).

Off the top of my head, about the only "instance constant" I can think of is something like:but I'm sure other people will prove me wrong.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike. J. Thompson wrote:One thing that hasn't been mentioned here is Exceptions. If the objects constructor can throw a checked exception then you cannot instantiate it inline.

Excelent point. I'd completely forgotten about that.

Winston
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With very few exceptions, an instance field initialized eagerly could just as easily be made static; otherwise, if it's final, its value will normally come from something passed to a constructor (indeed, it's basically how you create immutable objects).

Off the top of my head, about the only "instance constant" I can think of is something like...


That only holds true if the type of the field is immutable or a primitive. Take the List example. You would assign the list once, is value doesn't come from the constructor, it's contents will change over time and you don't want a single List shared between all instances of the containing class. This would be a final instance variable. And that use case covers most of the objects I end up using that are not immutable
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:Take the List example. You would assign the list once, is value doesn't come from the constructor, it's contents will change over time and you don't want a single List shared between all instances of the containing class.

True, but I thought we'd already covered that. I'd also say that unless the List is specifically a LinkedList, there are things you might need to supply at construction time (capacity, for example). And in that case, I'd stick its initializer in the constructor.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:I'd also say that unless the List is specifically a LinkedList...

And actually, thinking it through a bit further, assuming your declaration is:

private final List<Whatever> = new LinkedList<Whatever>();   (as it probably should be)

you have the possibility that its implementation might be changed to something like ArrayList later, in which case you may well need an initial capacity...

Winston
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe I'm strange, but I'm yet to supply an ArrayList (or any other container) with an initial capacity. In fact I don't think I've ever tweaked the defaults of a container.

I also set eclipse to make all variables final unless they are assigned to after instantiation, so practically all of my instance fields are final. I only initialize them in the constructor if they depend on a constructor parameter or throw an exception etc.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike. J. Thompson wrote:Maybe I'm strange, but I'm yet to supply an ArrayList (or any other container) with an initial capacity.

What, not even HashMap? I almost always do. StringBuilder as well. Probably a bit AR of me, but as they say, it takes all sorts...

I also set eclipse to make all variables final unless they are assigned to after instantiation, so practically all of my instance fields are final.

I didn't even know you could. I'll be changing my settings today.

Cheers for that.

Winston
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You set Eclipse options to mark all fields parameters and local variables final, then when you try to assign to them and get an error, the list of possible solutions when you hover on the red triangle includes remove final modifier.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nope, I've never set initial capacity on a HashMap or a StringBuilder. I guess I've just never had a performance issue that could be solved by setting one.

As for Eclipse automatically setting variables as final, I believe its a cleanup rule. You can set the cleanup to be performed each time you save (and can do the same with the auti-formatter I think).
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!