具有Getter / Setter与公共列表的私人列表

时间:2014-06-01 19:07:39

标签: java list getter access-modifiers

将类中的全局列表设为私有并使用getter和setter方法会更好吗?或者将它公开更好吗? Java中的标准是什么?

我被教导要将变量设为私有,并且只使用getter和setter方法,但访问公共列表肯定比私有更好。

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

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

这是我的看法,但当然我更倾向于遵循标准,而不是看起来很好看。

4 个答案:

答案 0 :(得分:2)

首先,您不应直接使用public字段,除非它们是常量(static final)字段,确保其状态不会更改。应使用Encapsulation公开它们,以避免类的客户端修改状态。这是一个通过以防御方式实现getter / setter编写自己的框架的示例,以便不改变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);
    }
}

除此之外,JavaBean specification声明Java类中的字段不应该是public,并且它们的访问应该通过getter和setter方法。

  

7个属性

     

属性是Java Bean的离散命名属性,可以影响其外观或行为。例如,GUI按钮可能具有名为“Label”的属性,该属性表示按钮中显示的文本。

     

属性以多种方式显示:

     
      
  1. 属性可能会在脚本环境中公开,就好像它们是字段一样   对象。所以在Javascript环境中我可能会用“b.Label = foo”来设置a的值   属性。
  2.   
  3. 可以通过调用其getter的其他组件以编程方式访问属性   和setter方法(见下面的7.1节)。
  4.         

    (...)

         

    7.1存取方法

         

    始终通过对其拥有对象的方法调用来访问属性。对于可读属性,将有一个 getter 方法来读取属性值。对于可写属性,将有一个 setter 方法,以允许更新属性值。

有些框架遵循这些规范,以允许通过反射注入/检索类字段的值。例如,Spring和JSF。

通过XML配置的Spring示例:

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

关联的Java类:

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;
    }
}

使用Expression Language进行字段绑定的JSF示例:

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

关联的Java类:

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;
    }
}

使用哪个选项:防御性getter / setter或常见的getter / setter?这取决于你正在做什么。

答案 1 :(得分:1)

标准是拥有私有实例变量和公共getter / setter方法(就像你被教导过的那样)。你总是希望封装或者隐藏&#34;数据,这是OOP的基本概念之一。这个(以及其他)的主要好处之一是修改我们实现的代码,而不会破坏可能使用相同代码的其他开发人员的代码。这种方法还将增加可维护性。

答案 2 :(得分:0)

我会更进一步:

为什么要知道如何存储数据? 信息隐藏是关键字。在您的示例中有关数据类型 leak 的详细信息。关键字 list 泄漏了有关实现的详细信息,即1)不必要的信息 - 您甚至可以将其命名为 treasurechest 2)您的类的可能用户是否对实现做出假设,这是一件坏事。为您的班级提供 -name,例如 goodies ,并将方法命名为 put / pull 。如果你想添加多个元素,我会使用更通用的界面,如 Iterable

答案 3 :(得分:0)

最好在类中创建一个私有List并使用getter和setter方法

使用getter / setter

有一些优点
  • getters和setter可以在其中进行验证,字段不能
  • 使用getter,你可以得到想要的类的子类。
  • getter和setter是多态的,字段不是
  • 调试可以简单得多,因为可以放置断点 在一个方法中,不在该给定字段的许多引用附近。
  • 他们可以隐藏实施变更

更详细地了解以下链接

Advantage of set and get methods vs public variable

Why use getters and setters?