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

Java 具有Getter/Setter的私有列表与公共列表,java,list,getter,access-modifiers,Java,List,Getter,Access Modifiers,在类中创建一个全局列表并使用getter和setter方法是更好的选择,还是只将其公开?Java的标准是什么 我被教导将变量设置为私有的,只使用getter和setter方法,但访问公共列表显然比访问私有列表要好 public exampleclassThatContainsTheList.goodieList.add("Candy"); private exampleclassThatContainsTheList.setGoodieList(exampleclassThatContains

在类中创建一个全局列表并使用getter和setter方法是更好的选择,还是只将其公开?Java的标准是什么

我被教导将变量设置为私有的,只使用getter和setter方法,但访问公共列表显然比访问私有列表要好

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

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

这是我的观点,但我当然更愿意按照标准行事,而不是按照看起来不错的标准行事。

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

我会更进一步:


为什么有人知道你是如何存储数据的?信息隐藏是关键词。在您的示例中,有关数据类型泄漏到外部的详细信息。关键字列表泄露了有关实现的详细信息,这是1)不必要的信息-您甚至可以将其命名为2)您的类的可能用户是否对实现进行了假设,这是一件坏事。给你的类一个域名,比如goodies,给方法命名,比如put/pull。如果你想添加多个元素,我会使用一个更通用的接口,比如Iterable

最好在私有类中创建一个全局列表,并使用getter和setter方法

使用getter/setter有一些优点

  • getter和setter可以在其中进行验证,而字段不能
  • 使用getter可以得到想要的类的子类
  • getter和setter是多态的,而字段不是多态的
  • 调试可以简单得多,因为可以放置断点 在一个方法中,不靠近该给定字段的多个引用
  • 它们可以隐藏实现更改
要了解更多详细信息,请通过以下链接


首先,您不应该直接使用
公共
字段,除非它们是常量(
静态最终
)字段,并且确保它们的状态不会改变。应该使用公开它们,以避免类的客户端修改状态。下面是一个例子,当您编写自己的框架时,为了不改变
列表的当前状态,以防御方式实现getter/setter:

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);
    }
}
以及相关的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;
    }
}
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;
    }
}
package my.package;
公开课Foo{
私人名单;
公共字符串getStringList(){
返回此.stringList;
}
//允许Spring通过反射设置stringList的值
公共无效设置字符串列表(列表字符串列表){
this.stringList=stringList;
}
}
JSF字段绑定示例使用:


#{value}
以及相关的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;
    }
}
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;
    }
}
package my.package;
@ManagedBean
@视域
公开课Foo{
私人名单;
@施工后
公共void init(){
stringList=新列表();
stringList.add(“Hello”);
添加(“世界”);
}
公共字符串getStringList(){
返回此.stringList;
}
公共无效设置字符串列表(列表字符串列表){
this.stringList=stringList;
}
}

使用哪个选项:防御型getter/setter还是普通getter/setter?这将取决于您正在做什么。

最好将私有实例成员与公共getter/setter一起使用,以避免对变量状态进行不必要的修改。在这里,setter方法充当安全警卫。它提供单点接触。阅读更多关于为什么不使用一个方法
add()
来获取对象
“Candy”
,并将其添加到列表中<代码>包含列表的类。添加(“Candy”)?虽然不是用石头写的,但在这些情况下提供了一些很好的建议。@antoh如果我这样做了,我不需要添加与集合相关的所有其他方法吗?不是必需的,但如果我打算使用它们,我也可以这样做。@dalaw您可以添加提供所需功能的方法。如果您只需要添加和删除,只需使用执行这些操作的方法即可。这些方法将以经典的方式作用于列表。我不是说这是最好的方式,但这是一个可能考虑的问题。这个答案是非常清楚的,代码示例说明并解释了需要做什么。非常感谢。