3

Would it be better to make a global List in a class private and have getter and setter methods or would it be better to just make it public? What is the standard in Java?

I was taught to make variables private, and just have getter and setter methods, but it definitely looks better accessing a public list than a private one.

public exampleclassThatContainsTheList.goodieList.add("Candy");

private exampleclassThatContainsTheList.setGoodieList(exampleclassThatContainsTheList.getGoodieList().add("Candy"));

That's my opinion, but of course I would prefer to go by standards than to go by what looks good.

dalawh
  • 886
  • 8
  • 15
  • 37
  • It's good way to use private instance member along with public getter/setter to avoid unwanted modification in the state of the variable. Here setter method works as **security guard**. It provides single point of contact. Read more about [Encapsulation](http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29) – Braj Jun 01 '14 at 19:10
  • 1
    Why not have a method `add()` that takes the object `"Candy"` and adds it to the list? `classThatContainsTheList.add("Candy");` ? – AntonH Jun 01 '14 at 19:10
  • 2
    Though not written in stone, the [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter) provides some good advice in these situations. – Mark Peters Jun 01 '14 at 19:12
  • @AntonH If I did that, wouldn't I be required to add all the other methods related to a collection? Not required, but I might as well if I was going to use them. – dalawh Jun 01 '14 at 19:12
  • This is called encapsulation. The benefits are numerous, but generally fall under the umbrella of abstraction. You can change what the `get` method does without breaking dependent classes. You cannot do this with direct member access. – Boris the Spider Jun 01 '14 at 19:12
  • 1
    @dalawh You add the methods that give the functionality you need. If you only need add and delete, just have methods that do these. The methods would act on the list in the classic way. I'm not saying it's the best way, but it is a possibility to consider. – AntonH Jun 01 '14 at 19:13
  • @MarkPeters If I provide a getter and setter method to a private List, it would ultimately be the same? – dalawh Jun 01 '14 at 19:14
  • @dalawh: The advantage of only implementing what the clients need is that you can change the underlying implementation details later. For example, if you want to change it to be a `Set` rather than a `List`, you can do that. But if you expose the list and clients start relying on, say, `getGoodieList().get(2)`, you can't do that. – Mark Peters Jun 01 '14 at 19:15
  • @BoristheSpider I am aware of that, but I don't plan on adding additional functionally. Back to your statement; are you recommending I make it private? – dalawh Jun 01 '14 at 19:16
  • @MarkPeters Understood. – dalawh Jun 01 '14 at 19:16

4 Answers4

2

First at all, you should not use public fields directly unless they are constant (static final) fields and making sure their state won't change. They should be exposed using Encapsulation to avoid a client of your class modifying the state. Here's an example when writing your own framework by implementing getter/setter in defensive way, in order to not alter the current state of your List:

public class Foo {
    private List<String> stringList;
    public Foo() {
        //always initialized, never null
        this.stringList = new ArrayList<>();
    }
    public List<String> getStringList() {
        //defensive implementation
        //do not let clients to alter the state of the list
        //for example, avoiding clear the list through getStringList().clear()
        return new ArrayList(stringList);
    }
    public void setStringList(List<String> stringList) {
        //defensive implementation
        //do not let clients to pass a null parameter
        this.stringList = (stringList == null) ? new ArrayList<>() : new ArrayList<>(stringList);
    }
}

Apart of this, the JavaBean specification states that fields in a Java class should not be public and their access should be through getter and setter methods.

7 Properties

Properties are discrete, named attributes of a Java Bean that can affect its appearance or its behavior. For example, a GUI button might have a property named “Label” that represents the text displayed in the button.

Properties show up in a number of ways:

  1. Properties may be exposed in scripting environments as though they were fields of objects. So in a Javascript environment I might do “b.Label = foo” to set the value of a property.
  2. Properties can be accessed programmatically by other components calling their getter and setter methods (see Section 7.1 below).

(...)

7.1 Accessor methods

Properties are always accessed via method calls on their owning object. For readable properties there will be a getter method to read the property value. For writable properties there will be a setter method to allow the property value to be updated.

There are frameworks that follow these specifications in order to allow injection/retrieval of values for class fields through reflection. For example, Spring and JSF.

Spring example through XML configuration:

<bean id="fooBean" class="my.package.Foo">
    <property name="stringList">
        <list>
            <value>Hello</value>
            <value>World</value>
        </list>
    </property>
</bean>

And the associated Java class:

package my.package;

public class Foo {
    private List<String> stringList;
    public String getStringList() {
        return this.stringList;
    }
    //allows Spring to set the value of stringList through reflection
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }
}

JSF example for field binding using Expression Language:

<!-- allows JSF to call getter through reflection -->
<h:dataTable value="#{foo.stringList}" var="value">
    <h:column>
        #{value}
    </h:column>
</h:dataTable>

And the associated Java class:

package my.package;

@ManagedBean
@ViewScoped
public class Foo {
    private List<String> stringList;
    @PostConstruct
    public void init() {
        stringList = new List<>();
        stringList.add("Hello");
        stringList.add("world");
    }
    public String getStringList() {
        return this.stringList;
    }
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }
}

Which option to use: Defensive getter/setter or common getter/setter? It will depend on what you're doing.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • This answer was really clear and the code sample illustrates and explains what needs to be done perfectly. Thank you. – Jeremy.S Jul 03 '15 at 08:53
1

The standard is to have private instance variables and public getter/setter methods (like you were taught). You always want to encapsulate or "hide" data, that is one of the fundamental concepts of OOP. One of the main benefits of this (among others) is to modify our implemented code without breaking the code of other developers who may be using the same code. This approach will also add maintainability.

ChristianF
  • 1,735
  • 4
  • 28
  • 56
0

I would go one step further:

Why should anyone know how you store your data? Information hiding is the keyword. In your example details about the datatype leak to the outside. The keyword list leaks details about the implementation, which is 1) unnecessary information - you could even name it treasurechest 2) does a possible user of your class make assumptions about the implementation, which is a bad thing. Give your class a domain-name like goodies and name the methods like put / pull. If you want to add multiple elements I would use a more generic Interface like Iterable.

Thomas Junk
  • 5,588
  • 2
  • 30
  • 43
0

It be better to make a global List in a class private and have getter and setter methods

There are some advantages of using getter/setter

  • getters and setter can have validation in them, fields can't
  • using getter you can get subclass of wanted class.
  • getters and setters are polymorphic, fields aren't
  • debugging can be much simpler, because breakpoint can be placed inside one method not near many references of that given field.
  • they can hide implementation changes

To know in more detail go through following links

Advantage of set and get methods vs public variable

Why use getters and setters?

:

Community
  • 1
  • 1
rachana
  • 3,344
  • 7
  • 30
  • 49