首先,除非它们是常量(
static final
)字段并且确保它们的状态不会改变,否则不应直接使用
public
字段。应该使用
封装来公开它们,以避免类的客户端修改它们的状态。以下是一个示例,当通过实现具有防御性的getter/setter来编写自己的框架时,以便不改变您的
List
的当前状态:
public class Foo {
private List<String> stringList;
public Foo() {
this.stringList = new ArrayList<>();
}
public List<String> getStringList() {
return new ArrayList(stringList);
}
public void setStringList(List<String> stringList) {
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;
}
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
}
使用
表达式语言进行字段绑定的JSF示例:
<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?这将取决于你正在做什么。
add()
的方法,将对象“Candy”添加到列表中呢?classThatContainsTheList.add(“Candy”);
- AntonHget
方法的操作而不会破坏依赖类。使用直接成员访问无法做到这一点。 - Boris the Spider