59

Where I work I see lots of classes that do things like this:

public class ClassThatCallsItsOwnGettersAndSetters {

    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public void methodWithLogic() {
        setField("value");
        //do stuff
        String localField = getField();
        //do stuff with "localField"
    }
}

If I wrote this from scratch, I would have written the methodWithLogic() like this instead:

public class ClassThatUsesItsOwnFields {

    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public void methodWithLogic() {
        field = "value";
        //do stuff            
        //do stuff with "field"
    }
}

I feel that when the class calls its own getters and setters, it makes the code harder to read. To me it almost implies that complex logic is happening in that method call even though in our case it almost never is. When I'm debugging some unfamiliar code, who's to say that the bug isn't some side effect in that method? In other words, it makes me take lots of side trips on the journey of understanding the code.

Are there benefits to the first method? Is the first method actually better?

2
  • When I'm debugging some unfamiliar code, who's to say that the bug isn't some side effect in that method? Your unit tests. :) Commented Jul 25, 2014 at 17:40
  • 1
    Using getters/setters in your internal code allows you to create a breakpoint in your code if you are going through it with a debugger. It also allows you to make sure that if anything is going wrong with setting setting/getting a value, you know that it is because of that method and not because of some invalid access. Overall, it provides for more consistence code. Commented Apr 13, 2016 at 16:06

9 Answers 9

51

I won't say which is better or worse, because that partly depends on your situation (in my opinion). But consider that your getters and setters may change implementation later, and bypassing them would skip that logic.

For example, what happens if you add a "dirty" flag to some setter fields later? By calling your setters in your internal code you'll set the dirty flag without changing any other code. In many situations this would be a good thing.

3
  • But what about when you're initializing the data in the backend and you don't want that to be interpreted as dirty. If you called setField() from the beginning you just introduced a bug. Commented Jan 4, 2013 at 20:38
  • 6
    Right, that's why I say it depends partly on the situation. Maybe your data initialization should skip the setters, but the other logical code shouldn't. Pick rules that are appropriate and stick with it.
    – Matt S
    Commented Jan 4, 2013 at 20:40
  • 3
    @DanielKaplan: the point is that calling getters and setters is in most cases the right thing to do, and only in specific situations not. However, in real world code, when you change an existing getter/setter-implementation later to introduce some intentional side effects, you will most probably have to check every call to the getter or setter inside the class, and also every direct access to the field. That's why you should try to keep your classes as small as possible.
    – Doc Brown
    Commented Jan 4, 2013 at 21:22
34

Calling the setter directly is not, in and of itself, a problem. The question really should be: Why does our code have setters everywhere?

Mutable classes are a dangerous game, particularly where the class itself manages its own state. Consider how many of those setters truly need to exist. How many could be set in the constructor and then become encapsulated entirely by the class itself?

If the field must be settable externally then ask yourself if the method with logic should be there. Is your class itself really just a data/state class? Does this class have more than one responsibility?

Don't get me wrong, there will be cases where this is fine. I'm not saying that you should eliminate setters on classes with logic entirely. But these should be the exception, not the rule. And, in those few cases, it should be obvious which to access directly.

2
  • 1
    I completely agree/practice this line of thinking. I also think you bring up a point that is in fact more important than my question. That said, I don't feel like it directly answers my original question. Unless you're saying, "in the grand scheme of things your question doesn't matter". Which may also be true :) Commented Jan 4, 2013 at 21:00
  • @DanielKaplan: I am saying exactly that. :) I was torn between answer and comment with this one, but I genuinely don't feel that there's a correct answer that doesn't ask the bigger question.
    – pdr
    Commented Jan 4, 2013 at 21:40
10

Yes, the methods of your class should call the getters and setters. The whole point in writing getters and setters is future proofing. You could make every property a field and directly expose the data to the users of the class. The reason you build the getters and setters isn't necessarily because there is complex logic now but so that the interface doesn't break in the future if you have to add it.

3
  • 1
    I don't see the relation between your first sentence and the rest of your paragraph. The first sentence says that a class should call its own getters and setters. The rest of the paragraph explains why client code (ie: code using the class) should use the getters and setters instead of accessing the fields directly. But I don't see how that is reason the class shouldn't directly access its own fields. Commented Jan 4, 2013 at 21:08
  • 1
    @DanielKaplan My point is that the reasons are one and the same. That if you add setter logic later, it impacts internal code just as much (potentially) as external.
    – Michael
    Commented Jan 4, 2013 at 22:12
  • 3
    @Michael: There can often be good reasons for a class to not use its own getters/setters. One common scenario is where there are many setters of the form someField=newValue; refresh(); If method allows multiple fields to be set, calling setters to write those fields would cause redundant "refresh" operations. Writing all fields and then calling refresh() once may yield more efficient and smoother-looking operation.
    – supercat
    Commented Jul 15, 2014 at 22:08
8

To answer your questions in one word, yes.

Having a class call its own getters and setters adds extensibility and provides a better base for future code.

Say you have something like this:

public class Vehicle
{
    private int year;
    private String make;

    public Vehicle(int year, String make)
    {
        setYear(year);
        setMake(make);
    }

    public void setYear(int year)
    {
        this.year = year;
    }

    public void setMake(String make)
    {
        this.make = make;
    }
}

Calling the setters for year and make currently may not add any functionality, but what if you wanted to add something like input validation to the setters?

public class Vehicle
{
    private int year;
    private String make;

    public Vehicle(int year, String make)
    {
        setYear(year);
        setMake(make);
    }

    public void setYear(int year)
    {
        if(year > 0)
        {
            this.year = year;
        }
        else
        {
            System.out.println(year + " is not a valid year!");
        }
    }

    public void setMake(String make)
    {
        this.make = make;
    }
}
6

One thing that hasn't been mentioned is that getter and setters (as all methods) are virtual in Java. This adds another feature to always using them in your code. Another user could extend your class, overwriting your getters and setters. Your base class would then be using the subclass's data instead of its own. In a language where you explicitly mark virtual functions, this is much more handy since you can predict and declare which functions this can be done with. In Java, this is something you would always have to be aware of. If it is desired behavior then using them in your code is a good thing, otherwise not so much.

3

If you are trying to accomplish something that is provided by the public interface, then use the getters/setters.

However, as the owner/developer of the class, you are allowed to access the private sections of your code (from within the class of course), but you are also responsible for mitigating the dangers.

So maybe you have a getter that iterates over some internal list, and you want to get the current value without incrementing the iterator. In this case, use the private variable.

public class MyClass
{
    private int i;
    private List<string> list;
    public string getNextString()
    {
        i++;
        return list[i];
    }

    private void getString()
    {
        // Do not increment
        string currentString = list[i];

        // Increment
        string nextString = getNextString();
    }
}
1
  • Can you give the reasoning for this? Commented Jan 9, 2013 at 18:04
1

Yes. Getters and setters represent state, so turn this question around -- do you want to have to keep track of multiple ways of changing an objects state in the same manner unless you have to?

The fewer things you have to keep track of the better -- this is why immutable objects are easier to deal with.

Consider, there is nothing preventing you from having both a public field and a public getter/setter -- but what would you gain?

It may on occassion be desirable or even necessary to directly access the field for one or more reasons, you shouldn't shy away from that if it happens. But you should really only do it if there is a defined benefit to doing so.

3
  • The point of my question is that I'm only asking about direct access of the fields in the same class. I already understand the purpose of getters and setters for client code. Commented Jan 5, 2013 at 22:06
  • @DanielKaplan: I understand that, and what I am saying is that as far as practical you should treat them the same.
    – jmoreno
    Commented Jan 5, 2013 at 22:47
  • @DanielKaplan: You could have one private setter and one public setter, that have the exact same result (all side effects the same) at least for the momement, but what would that gain you other than the potential for things to diverge? The difference between this scenario and what you describe is that you can't avoid being able to access the state outside of the getters/setters, but you can avoid actually doing so. Don't complicate your code unless you have to.
    – jmoreno
    Commented Jan 5, 2013 at 23:03
1

Both methods have their use cases. As public setter keeps field value (and/or bound values) consistent, you should use setter when your method logic does not interfere with this consistency logic. If you just set your "property", use setter. On the other hand, there are situations, where you need direct access to some fields, for example bulk operations with heavy setter, or operations where setter concept is too simple.

It is your responsibility to keep things consistent. Setter does this by definition, but cannot cover complex cases.

1

I would say No..

If your getters/setters just get and set (no lazy initialization, no checks, etc) then just use your variables. If in the future you change your getters/setters, you can very well change your methodWithLogic() (because its your class that's changing) and you can call a getter/setter instead of direct assignment. You can document this call for the getter/setter (as it will be strange to call a getter/setter when the rest of your class code is directly using the variable).

The JVM will inline frequent calls to getters/setters. So, its never a performance issue. The gain of using variables is readability and IMHO, I would go for it.

Hope this helps..

Not the answer you're looking for? Browse other questions tagged or ask your own question.