J. Doe
J. Doe

Reputation: 105

Which is better practice, using private variables or public methods within the class?

Example:

private int x = 4;

public TestClass(int x) {
    this.x = x;
}

public TestClass(int x) {
    setX(x);
}

public void setX(int x) {
    this.x = x;
}

Is the first constructor better practice or the second? I'm asking this because when I encapsulate my classes in IntelliJ IDEA if I used this.x = x before, it changes it to setX(int newX);.

Upvotes: 4

Views: 546

Answers (4)

Chris Parker
Chris Parker

Reputation: 426

You've already accepted an answer, but still, I see something nobody has mentioned. A setter makes your class mutable (at least without guard conditions), which may or may not be a good thing. However, it's much easier to make your class immutable if you supply the value to the constructor.

Immutable classes are inherently thread-safe, and should be preferred whenever practical. So in your (admittedly extra simple) example, I would favor using the constructor, and I would have only a getter for the value.

IMO, having a constructor that takes a value and a setter that sets that same value is a code aroma if not smell.

Upvotes: 0

Jacob G.
Jacob G.

Reputation: 29680

For the most part, it's all personal preference. I would use the first constructor if its value did not depend on other variables. However, setter methods allow for certain conditions to be met before modifying the value of a variable. For example:

private int x;

public TestClass(int x) {
    setX(x);
}

public void setX(int x) {
    // Some random condition depending on other variables.
    if (System.currentTimeMillis() & 1 == 0) {
        this.x = 5;
    } else {
        this.x = x;
    }
}

It would make sense to use a setter method if there were many conditions that could not be easily represented by a ternary statement.

If the class is abstract, then a concrete class that extends it could possibly override the setter method, thus modifying the value of the variable. If you plan on using self-encapsulation and don't want any child class to override the setter method, simply add the final keyword to the method declaration.

Upvotes: 1

user3458
user3458

Reputation:

It depends.

The derived classes can override the setter, and you need to decide if the effects of the override are good or bad in a particular place.

My opinion is that if the setter is documented to be overridable, you need to pay attention to using setter vs. the assignment. If you do not document the setter to be overridable, then just use the assignment.

Upvotes: 1

seal
seal

Reputation: 1143

There is a term called Self Encapsulation. Martin Fowler wrote a blog on this topic. Blog Link. To summarize this sometime you may have initialization or assign logic in the setter. So I think, it is better to call setter whenever you are going to initialize or assign value.

Upvotes: 0

Related Questions