0

I'm designing an API function of a class which will return an array for client to use.But I'm not quite sure whether I should make it a return value or make it as an argument of the function.See below:

Method I:

MyObject[] getMyObject() {... return someObject;}

Method II:

void getMyObject(MyObject[] someObject) {...//assign value to someObject[index]};

In Android API I saw it is very common to return a List<MyObject> or Set<MyObject>. Does it indicate Method I is better? So what are the pros and cons of these two methods in Java?

Update: In method II I mean to assign value to someObject[index], not someObject. My question is not regarding "does Java pass reference or value". It's just simply comparing two feasible way of doing things.

5
  • 1
    In method 2, if you assign value to someObject it will have no effect after the method is done. I hope you mean assign values to the indexes of someObject. Commented Aug 28, 2013 at 0:56
  • 2
    "OUT" params tend to be frowned upon, for a variety of reasons, assuming you actually meant that you'd fill the passed-in array rather than trying to set it to something. Also, are you certain you want an array? Commented Aug 28, 2013 at 0:57
  • @jlordo Of course it is for a certain index. I will update and make it clear. Commented Aug 28, 2013 at 1:03
  • @DaveNewton So what do you suggest when I want to return a series of data in an Java API? List? Commented Aug 28, 2013 at 1:10
  • One thing to keep in mind is also Java convention: if you have a method called getX(), one should always expect that an object of type X will be returned. For method 2, it might make more semantic sense if it were called something like fillMyObject. Commented Aug 28, 2013 at 1:22

4 Answers 4

2

Arrays are not resizeable. So with method 1, you can create a new array with just the right size and return that. With method 2, if the incoming array is the wrong size, you're sunk.

Java does not have pass-by-reference. So assigning something to someObject in method 2 won't do anything for the caller. You can only alter the elements of someObject.

Sign up to request clarification or add additional context in comments.

Comments

1

Both ways have advantages and disadvantages.


Version #1

MyObject[] getMyObject() {... return someObject;}

Pros:

  • This allows you to return an arbitrary number of results.
  • It is arguably easier for the caller.

Cons:

  • The called method has to allocate an array. (Alternatively, it has to manage / recycle arrays, which is going to be difficult to do in general. Note that reusing a static array is liable to make the method non-reentrant, etcetera.)

Version #2

void getMyObject(MyObject[] someObject) {...//assign value to someObject[index]};

Pros:

  • This is potentially better in terms of objects allocated because the caller will be in a better position to recycle / reuse the array.
  • It allows you to pass values in ... if that is a requirement.

Cons:

  • The caller has to provide the array, which makes the method more work to use.
  • The called method has no control over the array size. That means that there is a potential error case if the supplied array is too small ...

There is also a third way, where an array is passed and returned. If the array size is not correct (or maybe if a null is passed) the called method allocates or reallocates an array. The result is either the original array or the reallocated array.


Which is better?

IMO, the first version is better under most circumstances because it is easiest to get right. IMO, you should only consider the alternatives in an API design if there is a demonstrable need to minimize new object allocation. (If you are coding for a Hotspot Java implementation or equivalent, new object allocation is cheap ...)

Finally, a simpler / cleaner way than all of the above is to use a Collection rather than a bare array. Using a standard Collection type allows you to avoid the messiness of preallocating something of the correct size.

2 Comments

Thanks! Regarding your last point on Collection, there still exist two options(making it as return value or argument). In this case we don't need to handle any pre-allocation stuffs, but still, which method is better or more often used?
There is rarely any point in the caller passing an empty collection to the called method to be populated. The only case would be if the caller required a particular collection implementation class ... and that would be better handled by passing a factory object.
1

Return is more natural to write and read, also pass by "reference" as you call it has more complications than meets the eyes..

someObject[i] = a; //works

someObject = a; // doesnt work

Comments

1

Java has one parameter passing mechanism: everything is passed by value, not by reference.

It's subtle, but true. The implications matter.

You can certainly return any time from that method, be it array, List, or Set. You may or may not be able to alter the contents of the List or Set, because the implementation underneath might have been made unmodifiable by the developer who wrote the method.

Personally, I tend to prefer the collections over arrays. They are more expressive than raw arrays. If I get a Set back, I know that all the entries are unique in some way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.