当前位置: 首页 > 知识库问答 >
问题:

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

许华清
2023-03-14

在私有类中创建一个全局List并具有getter和setter方法会更好,还是只公开它会更好?Java的标准是什么?

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

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

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

这是我的观点,但我当然更喜欢按照标准去做,而不是按照看起来好的去做。

共有3个答案

缪坚诚
2023-03-14

我会更进一步:

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

羊舌高爽
2023-03-14

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

白星海
2023-03-14

首先,您不应该直接使用public字段,除非它们是常量静态最终)字段并确保它们的状态不会改变。它们应该使用封装公开,以避免您的类的客户端修改状态。这是一个通过以防御方式实现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规范声明Java类中的字段不应该是public,它们的访问应该通过getter和setter方法。

7 房源

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

属性以多种方式显示:

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

(...)

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

使用表达式语言进行字段绑定的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/seter?这将取决于你在做什么。

 类似资料:
  • 如何在Kotlin中创建一个具有私有getter(或只是没有)但具有公共setter的属性? 不能使用错误: 在我的例子中,原因是Java Interop:我希望我的Java代码能够调用,但不能调用。

  • 我希望我的类有一个字段,该字段返回所有公共访问的不可变列表,但在对象实例中,我希望列表是可变的,以便我可以向其添加元素。 我试过了,但不确定这是否被视为良好做法?

  • 我有一个基类,它使用php魔术方法__get和__set,可以修改扩展类中的私有属性。然后,我为相关的私有属性构建setter getter函数(类似于http://www.beaconfire-red.com/epic-stufle/better-getters-and-setters-php)

  • 我可以在kotlin中使用相同的方法,只需简单地编写getter函数,但这看起来不像kotlinlike方法。有没有更好的方法来实现与此相同?

  • 在测试类下面,我想过滤所有部分中的公共语言列表。 例如,测试有药剂列表P1和P2。P1有一个列表 最终输出应该是包含Ja和Zh语言的语言对象列表。

  • 我想从一个对象中获得一个具有公共超级类的字段列表,然后迭代它们并执行超级类中存在的方法。示例: 所以从BasePage类,我想实现检查方法,它应该解析一个页面的字段列表,然后得到具有超级类basElement的字段列表,然后为每个启动方法存在。我确认它不是反射私人领域的复制品