What are the pro's and con's of calling out to a mutator from a constructor (if any)
i.e.:
public MyConstructor(int x) { this.x = x; }
versus:
public MyConstructor(int x) { setX(x); } public void setX(int x) { this.x = x; }
Do you have a preference? (This is not homework, just looking at our coding standards doc where it says to always call out to mutators when setting instance var's in the constructor and I don't always to this)
Yes, calling instance methods from constructors can be hard to reason about, and is not generally preferred. Now, if you want to move your validation logic into a private, final class/static method, and call it from both the constructor and setter, that would be fine.
In simple terms: Use constructor if you think initialization is mandatory before you can use the object. Use setter method when initialization of variable is non-mandatory to use the object.
Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value.
Use Setter injection when a number of dependencies are more or you need readability. Use Constructor Injection when Object must be created with all of its dependency.
Personally, I would set the variable directly in most cases.
Methods usually expect that the instance is fully-formed by the time they're called. In particular, calling an overridden method from a constructor is a recipe for hard-to-understand code and hard-to-spot bugs.
Having said that, I often try to make classes immutable anyway, in which case not only is there no setter, but you have to set the final variable from the constructor (or a variable initializer) anyway :)
Where properties have logic, setter logic is usually validation and sometimes change propagation to observers. I'd usually expect the constructor parameters to be checked explicitly at the start of the method, and you wouldn't want any change propagation to occur before an instance is fully created anyway.
I follow two rules about constructors to minimize problems which are why I would not use the mutator method:
Constructors (of non-final classes) should call only final or private methods. If you decide to ignore this rule and let the constructor call non-final/non-private methods, then:
Is all that extra cognitive baggage worth it? You could allow an exception for simple mutators that only assign a value to an instance variable, since there's little benefit, even that doesn't seem worth it.
[[ @Jon Skeet mentions this in his answer: "... In particular, calling an overridden method from a constructor is a recipe for hard-to-understand code and hard-to-spot bugs." But I don't think the ramifications of this problem is stressed enough. ]]
Constructors should be cautious about leaking this
before the instance is fully initialized. While the previous rule was about methods inside the class and subclasses accessing ivars, you must also be careful about (even final/private) methods passing this
to other classes and utility functions before this
is fully initialized. The more non-private, overridable methods that the constructor calls, the greater the risk of leaking this
.
Some references about constructors calling non-final, non-private methods:
https://www.securecoding.cert.org/confluence/display/java/MET05-J.+Ensure+that+constructors+do+not+call+overridable+methods
http://www.javaworld.com/article/2074669/core-java/java-netbeans--overridable-method-call-in-constructor.html
http://www.javaspecialists.eu/archive/Issue210.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With