Java Conventions: use getters/setters WITHIN the class?

JavaCoding Style

Java Problem Overview


My professor really emphasizes protecting against privacy leaks by always using accessors and mutators to access private instance variables; however, do I have to use the getters/setters of a class within the class?

So for instance, if I have the following class:

public class Person 
{
	private String name;
	private int age;
}

and I want to write a toString() method for it. Can I just write:

public String toString()
{
	return name + " " + age;
}

OR do I need to do something like this:

public String toString()
{
	return this.getName() + " " + this.getAge();
}

Java Solutions


Solution 1 - Java

You CAN do either one. However, your professor might appreciate using the methods instead of the direct access. Here's why.

Let's say you have a class like this:

class SomeClass {
    private int someValue;
    private String someString;

    public SomeClass(int someValue, String someString) {
        this.someValue = someValue;
        this.someString = someString;
    }

    public int someValue() {
        return this.someValue;
    }

    public String someString() {
        return this.someString;
    }

    public String toString() {
        return someValue + ": " + someString;
    }

}

It's pretty straightforward, right? Well, what if all of a sudden we want to CHANGE the implementation of how we calculate someValue, and base it off of someString:

public int someValue() {
    int value = 0;
    for(int i = 0; i < someString.length; i++) {
         if(someString.charAt(i) == ' ') value++;
    }
    return value;
}

Now you also have to change every place where variable someValue was used.

So if you want to make the code easier to maintain in the long run, use the methods calls. This way when you code changes on you (and trust me, it changes all the time) you only have to change it in one spot instead of two.

And yes, you would want to use a method call in getting someString instead of the direct access in the last method :-)

Solution 2 - Java

When I design a class I try to make a clear distinction between the inside (implementation details) and the outside (the interface exposed to the world). Getters and setters provide a convenient place to convert values between the form in which they are stored in the object’s instance members and the form in which the outside world sees them. Using getters and setters internally would muck that up, because they'd be getting used by both the inside and outside.

If you find yourself wanting to hide part of a class from another part of the same class, consider breaking off the part you want to hide into its own class.

Solution 3 - Java

It's normally not a good idea, for a number of reasons:

  • You may not even want accessors for all fields
  • Some accessors may make a defensive copy so not to expose internal state, this is normally unnecessary within the class where you know that you are not going to modify it - or plain wrong if you know you ARE going to modify it
  • It makes debugging more annoying, because you have to follow the getters / setters
  • It makes reading the code harder in most IDEs, since most of them color fields differently than local variables

... but as always, there are exceptions. Some setters may have side-effects (for example setting a second value) that you WANT to execute, then it might be better to use the setter. Also, if you design your class for inheritance, it may be better to go via an accessor if you want the subclass to be able to alter the behavior.

Solution 4 - Java

In general, no. If your getter returns something other than the value of the field then you should use the method, but in that rare case your method should have a more descriptive name. For a bad example, if you have:

public void setName(String name)
{
  _name = name;
}

and your getter returned something else, like

public String getName()
{
  return _name.toUpperCase();
}

then yes, you should use the getter. It would be better, though, to have a more descriptive name for that getter:

public String getNameAsUppercase()
{
  return _name.toUpperCase();
}

Solution 5 - Java

You can use the accessors and mutators, but its a messy standard to follow.

It clutters up your code and confuses anyone trying to read it thinking it might not be a part of your class.

Basically, just access the variables directly from inside your class, and indirectly from anywhere else.

Solution 6 - Java

On the flip side, consider it from a design standpoint. One of the motivations for getters/setters is that the underlying data storage can change and things that implement the class won't need to be changed since it is encapsulated.

So, keeping that in mind, using getters/setters within the class makes future changes easier. Instead of having to find all the places that alter the member directly, you just have to change the getter/setter. Depending on the complexity of the class, this may significantly reduce the amount of work it takes to change the storage members.

For example, let's assume you start out with the age variable in years. Then you decide later to store it as seconds for some reason. But you want to always print it in years anyway. So in your example, you could do the math in your toString() function (and anywhere else that wants years as the units) or you can just change the math in the getAge() routine to return years from the seconds and nothing else has to change.

Obviously that example is a bit trivial. The more complicated the class, the more useful it is to use getters/setters within it.

Solution 7 - Java

No, you don't. You can access any variables, private, public or protected, from within the class.

Here are some tables to help you:

enter image description here

Source: Java Tutorials

Solution 8 - Java

If your class (or the accessor methods in question) is not final, then you should definitely use the accessor methods.

If another class extends yours and overrides those accessors, your class should use the overridden accessors. If this would break your superclass, then your superclass is designed incorrectly; prevent those accessors from being overridden with final, or change the design of your class.

Solution 9 - Java

No you can use directly your instance variables inside the class, you're not violating any "rule". Getters and setters are mandatory for others classes to access instance variables of a class to not violate the encapsulation principle (which is quite important in OO programming).

In the end it's a matter of choice, but you're saving one method call using your first example.

Solution 10 - Java

I think we should use getters() and setters() instead of accessing directly. It is also makes debugging very easy; for example, if you need to assign a variable to multiple place in your class and later want to find out from how many places the variable is assigned to, then you need to find all the assignment and set the break point.

However, if you use a setter you can simply put a break point inside the setter method and can see how many time the variable is assigned.

Solution 11 - Java

I use a mix of both. Accessor methods add more clutter so I use them only when the variable is used many times. If the variable is used only once or twice I don't use them.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLTHView Question on Stackoverflow
Solution 1 - JavacorsiKaView Answer on Stackoverflow
Solution 2 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 3 - JavawaxwingView Answer on Stackoverflow
Solution 4 - JavaPaulView Answer on Stackoverflow
Solution 5 - JavaJon EgelandView Answer on Stackoverflow
Solution 6 - Javatpg2114View Answer on Stackoverflow
Solution 7 - JavaeboixView Answer on Stackoverflow
Solution 8 - JavaericksonView Answer on Stackoverflow
Solution 9 - JavatalnicolasView Answer on Stackoverflow
Solution 10 - JavaSharifView Answer on Stackoverflow
Solution 11 - JavaJeffreyView Answer on Stackoverflow