Java 布尔值 setter,根据命名约定带有 "has" 前缀

Java boolean setter with "has" prefix according to naming convention

简单的问题,但我听不懂。

带有 is 前缀的示例:

private boolean active;

public boolean isActive(){...};//getter

public boolean setActive(boolean b){...};//setter

但我不明白如何使用 has 前缀 setter

private boolean hasChildren;

public boolean hasChildren(){...};//getter

public boolean  ?(boolean b){...}//setter

当我们在谈论 hasChildren 、 hasAttributes 时,我们在谈论是否有任何集合附加到它。就像 children 可以是很多,例如可以是列表或地图,而在 isActive 的情况下我们只是表示单个 属性 值。 您可以设置值 setHasChildren。但后来我认为命名约定是为了方便理解。

您可以安全地选择 setHasChildren,因为它完全清楚。不过,如果您正在存储有关 children 的更多信息,它可能会改变答案。

例如,如果您需要存储 children,只有 setter 才有意义,而 children 将由集合表示:

// no hasChildren attribute
private Collection<ChildClass> children;
public boolean hasChildren(){ return !children.isEmpty(); };
// no setter

另一个例子,如果你存储 children 的数量:

// no hasChildren attribute
private int childrenCount;
public boolean hasChildren(){ return childrenCount > 0 };
// no setter

对于布尔值,您可以使用 is 作为 getter 中的前缀,或者您也可以使用 get 作为前缀

public boolean isHasChildern();//getter
public boolean getHasChilder();//getter
public boolean setHasChildren(boolean active);//setter

hasChildren 正在检查 object 的状态,因此我通常不会期望 setter 方法。

我希望如果你没有 children (hasChildren() == false) 然后添加 addChild(Whatever) 那么下次你调用 hasChildren 时,它会 return是的。

通过尝试手动操纵该行为,您将破坏封装和得墨忒耳法则,因为您的调用程序应该知道其拥有的 object,但不知道其 object 的实现我们拥有 object。我希望这是有道理的。

打个粗略的比方,你可以问一位女士她是否和 child 在一起,她会(希望)报告她的状态(或者开始哭泣,因为你刚刚给她打电话 "large). If false, you could proceed to make her pregnant (subject to consent of course), you wouldn't just cram a baby up there and say " 那里,你“现在怀孕了”。

根据 JavaBeans Specification(第 8.3.2 节),布尔字段 foo 的访问器方法相应地是 isFoo()setFoo(boolean)

您的情况是访问器对 isHasChildren()/setHasChildren()

作为建议,您应该考虑将字段重命名为 boolean childrenPresent;,根据规范,这将派生为 isChildrenPresent()setChildrenPresent().

如果确实像您的代码中那样,您为此设置了 boolean,请继续使用 setHasChildren

通常,"has" 类属性没有简单的设置器,因为它们通常报告的状态不受简单布尔值的支持,例如:

private List<Child> children;
// ...
public boolean hasChildren() {
    return children.size() > 0;
}
// ...
public void addChild(Child c) {
    // ...
}

但如果情况并非如此,setHasXyz 也可以。

您遇到的问题不仅仅是为 setter 找到合适的名称。也是你的getter不符合约定!

specification and the tutorial 对此非常清楚:

  • 对于 属性 的 setter 应该以 set
  • 作为前缀
  • 非布尔值 属性 的 getter 应以 get
  • 为前缀
  • 布尔值 属性 的 getter 应以 is 为前缀

遵循这些约定很重要,因为否则,许多自动(基于反射的)工具将不再按预期工作(例如 Introspectors)。


抛开语法不谈,有几种方法可以解决这个问题。在评论中,有人建议调用 属性 isParent,但严格来说,访问器必须调用 isIsParent...

所以我建议简单地调用 属性 类似 havingChildrenowningChildren,并提供相应的访问器方法,如 isHavingChildren/setHavingChildren, 要么 isOwningChildren/setOwningChildren,分别。