简体   繁体   中英

Private List with Getter/Setter vs Public List

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.

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.

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.

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 .

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?

:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM