Wednesday, July 23, 2008

Methods accepting Variable Argument Lists in Java?


How to implement methods accepting Variable Argument Lists in Java?


Java doesn't have a built-in feature to handle variable argument lists to a method call, the way we have in C/C++. But, there are several alternative ways of achieving this in Java using simple programming constructs. Let's try to discuss these alternative ways:-


Method Overloading - it directly comes to our mind whenever we start thinking about a method which has the same name and different argument list (based on order, type, and number). We can obviously overload the method to have it accepting variable argument lists, but as it's quite evident that this approach will have two serious problems:-

  • Knowledge of various argument combinations at desgn time - unless we are aware of what all combinations of method calls we may encounter during run time how can we overload the method. So, we can't really achieve a generic variable argument lists call to the method following this approach.
  • Duplication of code - evidently most part of the code (except that which deals with the new arguments of the particular overloaded version) may be duplicate. This won't really cause any performance problem as the particular overloaded method will be bind at compile time itself, but it may certainly increase the size of the .class file of the particular class.


Using Object array - as we know that every class in Java either directly or indirectly extends the cosmic superclass named Object and hence an Object array (Object[]) as the parameter type of a method will enable the method to accept variable argument lists by accepting an Object[] of corresponding length. For primitive type arguments, we'll require to wrap them in their corresponding wrapper classes before adding to the Object array and un-wrapping them back inside the method. This approach is almost a complete equivalent of variable argument lists feature of C/C++, but the only problem with this approach is that in this case any changes made inside the method will actually change the original data as well (as is the case with any method using object references).



Using Collection framework - with the introduction of Collection framework in Java, we now have a better approach of handling a situation requiring a variable argument list to a method call. The reason is very simple that we can handle the problem of modifying the original object (which was the case with Object[] as discussed above) by first obtaining an unmodifiable collection object containing the variable argument lists before passing it as the method parameter. This will ensure that any changes made within the method on the passed collection object will cause an exception to be raised. Example: most commonly we use a List to handle such a situation. Once we are done with adding all the arguments to the List object then we simply retrieve a reference of the unmodifiable list by calling Collections.unmodifiableList(List originalList) and we pass this unmodifiable List object reference to the method.


Note: if we want to keep a modifiable reference of the List as well then we need to capture the return value of the method Collections.unmodifiableList(List) in a separate List reference otherwise if we assign that to the original reference then we won't have any reference to change the List either in the calling method OR in the called method. Be sure of what you want before deciding.


...

List originalVAList = new ArrayList();

//... obviously we can add any Object, not just a String

list.add("Argument #1");

list.add("Argument #2");

...

list.add("Argument #n");

//... retrieving unmodifiable List

List unmodifiableVAList = Collections.unmodifiableList(originalVAList);

...

//... call the method with the unmodifiable List reference

variableArgMethod(unmodifiableVAList);

...


Another advantage of using Collection framework instead of Object[] is that we don't need to bother about the trivial stuff like looping through the entire array to print, fetch the size, etc. as the Collection framework is rich enough to support all those features with very less coding and the implementation is supposedly either better or at least as good as what most of us can think of. So, using Collection framework to handle such a scenario is always advisable unless of course you have a very strong reason to do it otherwise.


Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


3 comments:

rayesh said...

Java methods can accept variable argument lists since Java 5.
It is possible to declare methods like the following:

public static void print(Object ... params){
  for(Object param : params){
    System.out.println(param.toString());
  }
}

Geek said...

Thanks rayesh for your inputs. Yeah Java 5.0 supports variable arguments using the syntax (...) as specified by you.

As it's quite evident that it internally uses the Collection framework only.

Any primitive type data is converted in an object of the corresponding wrapper class using Autoboxing - another feature introduced by Java 5.

loop map in java said...

Indeed varargs is a nice feature and works great on a particular type of method like sum(), avg() etc. By the way here is few more points worth noting on varargs method in Java. you may like.