So, I'm normally a ruby programmer, so my grasp of Java conventions is shaky at best. If I have a class A and want to define a method to add two instances of that class, what's the convention on the behaviour and return type?
public class A
{
//...
public NotSure开发者_如何学PythonWhatTypeItShouldReturn add (A that) { /* ... */ }
Should I
- return a boolean indicating success and modify the target, or
- return a modified copy of the target and throw an exception on error
Which fits with the normal Java convention for this kind of method?
Both exist: Collection.add
modifies the collection and returns a boolean, and BigInteger.add
returns a new BigInteger
that holds the sum of the original and the passed-in instance.
I generally expect most methods to modify the instance they're being called on, rather than returning a new object of the same type, but if there's a good use case for keeping instances const and returning a new instance all the time you can certainly do that
Don't return a boolean unless it's an "expected failure" e.g. trying to add to a set. If something actually goes wrong, throw an exception.
Now, you could return a modified copy - or you could add to the existing object. Immutability is often a nice property... but most collections in Java are mutable. If you're going down the immutable route you might want to consider using plus
instead of add
- it gives more of a feeling of "there's a result you should look at, and I won't change the target" IMO.
Everyone here is thinking about Collections.add()-type method; but I doubt that's what you're thinking. Are you more in the line of, say, Vector2D.add()
which adds the x and y component of the Vector2D together?
In Java, as far as I can tell, Collections generally modify themselves (and so does Collections.add).
However, non-Collections object (e.g. Vector2D) varies more. Among the conventions I've seen:
Cls add(Cls b)
which returns a new object and does not modify existing instancesvoid add(Cls b)
which modifiesthis
and returns nothing (i.e. returns void), it should not modifyb
. There is no point in returningbool
since this type of addition is never supposed to fail (and if it does anyway, an Exception would be appropriate).Cls add(Cls a, Cls b)
which returns a new object, modifies neither a nor b. Cls.add() is a static method in Cls class.
Personally, I prefer the first style for arithmetic-style add(); precisely because we can do a.add(b).add(c).add(d) which looks a bit like "a + b + c + d". (I wouldn't normally do this if a
is a Collection; since serial addition looks weird for Collections object.)
I would recommend the same behaviour as in Collection.add, this is what I would expect.
From the Java Collections API:
Ensures that this collection contains the specified element (optional operation). Returns true if this collection changed as a result of the call. (Returns false if this collection does not permit duplicates and already contains the specified element.)
Collections that support this operation may place limitations on what elements may be added to this collection. In particular, some collections will refuse to add null elements, and others will impose restrictions on the type of elements that may be added. Collection classes should clearly specify in their documentation any restrictions on what elements may be added.
If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns.
This is not really a convention, but only what boolean Collection<E>.add(E)
exemplifies:
Returns:
true
if this collection changed as a result of the call
Throws:UnsupportedOperationException
- if theadd
operation is not supported by this collection
Methods of the Java Collections Framework classes rarely returns the collection that they're invoked upon. That is, it's not idiomatic to support this:
mySet.add(thisThing).add(thatThing).add(thoseAlso);
Some classes in the Java libraries employ the "fluid" style, e.g. Appendable
such as StringBuilder
, but none of the main Java Collections Framework classes do.
Depends on the semantic of your class, but typically it would be:
public void add( A that ) {
}
If what you intend is just to aggregate elements.
You can use:
public boolean add( A that ) {
}
If your intention is to know if the structure was modified or not ( Like with a java.util.Set
or collections in general )
And you can use public A add( A that ){}
if your intention is to create a "builder like" object ( just like StringBuilder.append
method.
A a = new A();
a.add( a ).add( b ).add( c ).build();
So depending on the semantic of your class you could use either.
Most of the times (+90%) I do the first: void add( A other ){}
精彩评论