所以,我通常是一个红宝石程序员,因此我对Java约定的掌握充其量是不稳定的。如果我有一个A类并且想要定义一个方法来添加该类的两个实例,那么行为和返回类型的约定是什么?
public class A
{
//...
public NotSureWhatTypeItShouldReturn add (A that) { /* ... */ }
我应该
哪种方法适合这种方法的常规Java约定?
答案 0 :(得分:6)
两者都存在:Collection.add
修改集合并返回布尔值,BigInteger.add
返回一个新的BigInteger
,它保存原始实例和传入实例的总和。
我通常希望大多数方法修改它们被调用的实例,而不是返回相同类型的新对象,但是如果有一个很好的用例来保持实例const并且一直返回一个新实例当然可以这样做
答案 1 :(得分:5)
除非是“预期的失败”,否则不要返回布尔值。试图添加到一组。如果某事实际上错误,则抛出异常。
现在,您可以返回修改后的副本 - 或者您可以添加到现有对象。不变性通常是一个不错的属性......但Java中的大多数集合都是可变的。如果你要沿着不可变路线走下去,你可能想要考虑使用plus
而不是add
- 它会给人一种“你应该看到的结果”的感觉,我不会改变目标“IMO。
答案 2 :(得分:3)
这里的每个人都在考虑Collections.add() - 类型方法;但我怀疑那是你在想什么。您是否更喜欢将Vector2D.add()
添加到Vector2D的x和y组件中?
在Java中,据我所知,集合通常会自行修改(Collections.add也是如此)。
但是,非集合对象(例如Vector2D)的变化更大。在我见过的各种惯例中:
Cls add(Cls b)
返回新对象但不修改现有实例void add(Cls b)
修改this
并且不返回任何内容(即返回void),它不应修改b
。返回bool
是没有意义的,因为这种类型的添加永远不应该失败(如果它确实存在,则异常是合适的。)Cls add(Cls a, Cls b)
返回一个新对象,既不修改也不修改b。 Cls.add()是Cls类中的静态方法。就个人而言,我更喜欢算术风格的第一种风格的add();正是因为我们可以做a.add(b).add(c).add(d)看起来有点像“a + b + c + d”。 (如果a
是一个集合,我通常不这样做;因为对于集合对象,序列添加看起来很奇怪。)
答案 3 :(得分:1)
我会推荐与Collection.add中相同的行为,这是我所期望的。
答案 4 :(得分:0)
来自Java Collections API:
确保此集合包含指定的元素(可选操作)。如果此集合因调用而更改,则返回true。 (如果此集合不允许重复并且已包含指定的元素,则返回false。)
支持此操作的集合可能会限制可能添加到此集合的元素。特别是,某些集合将拒绝添加null元素,而其他集合将对可能添加的元素类型施加限制。集合类应在其文档中明确指出可以添加哪些元素的任何限制。
如果一个集合因为已经包含该元素的原因而拒绝添加特定元素,那么它必须抛出一个异常(而不是返回false)。这保留了在此调用返回后集合始终包含指定元素的不变量。
答案 5 :(得分:0)
这不是一个惯例,只是boolean Collection<E>.add(E)
举例说明的内容:
如果此次收集因调用而发生变化,则返回
true
抛出:UnsupportedOperationException
- 如果此集合不支持add
操作
Java集合的方法框架类很少返回它们被调用的集合。也就是说,支持这个并不是惯用的:
mySet.add(thisThing).add(thatThing).add(thoseAlso);
Java库中的某些类采用“流动”样式,例如: Appendable
,例如StringBuilder
,但没有主要的Java Collections Framework类。
答案 6 :(得分:0)
取决于您的课程的语义,但通常是:
public void add( A that ) {
}
如果你想要的只是聚合元素。
您可以使用:
public boolean add( A that ) {
}
如果您打算知道结构是否被修改(与java.util.Set
或一般的集合一样)
如果你打算创建一个“类似于构建器”的对象(就像public A add( A that ){}
方法一样),你可以使用StringBuilder.append
。
A a = new A();
a.add( a ).add( b ).add( c ).build();
因此,根据您班级的语义,您可以使用其中之一。
大多数时候(+ 90%)我会做第一次:{{1}}