Search code examples
javaperformancetheory

Equivalient method overload why necessary?


I browsed some JAVA code made by Google, and I found the ImmutableSet: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html

They implemented the of() method with several other ways:

public static <E> ImmutableSet<E> of(E e1, E e2);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5);
public static <E> ImmutableSet<E> of(E... elements);

I checked the implementation which is here:https://code.google.com/p/google-collections/source/browse/trunk/src/com/google/common/collect/ImmutableSet.java

There's a create method wiith the following signature:

private static <E> ImmutableSet<E> create(E... elements)

which wraps the

private static <E> ImmutableSet<E> create(Iterable<? extends E> iterable, int count);

method. The public methods just passes the parameters to the create(E... elements) signatured method which finally calls the other create method.

I guess that the public of methods with fixed count of parameter are unnecessary since we have the of(E... elements) method.

My question is that why did they do that like this? Performance? Or it's a pattern?

Thanks.


Solution

  • It can't be related to performance, actually: All the methods delegate to the same creation method, which expects an array anyhow.

    My guess is that it is related to warnings. Consider the following, minimal snippet:

    import java.util.List;
    
    class ImmutableSet<T>
    {
    }
    public class ParametersTest
    {
        public static void main(String[] args)
        {
            List<String> list0 = null;
            List<String> list1 = null;
            of(list0, list1);
        }
    
        @SuppressWarnings("unchecked")
        public static <E> ImmutableSet<E> of(E e1, E e2) {
            return create(e1, e2);
        }
    
        public static <E> ImmutableSet<E> of(E... elements) {
            return create(elements);
        }
    
        private static <E> ImmutableSet<E> create(E... elements) 
        {
            return null;
        }
    
    }
    

    The call to of in the main method is fine: It matches the 2-args-version of the of method. Now comment out the 2-args-version of the of-method. Then the call is still OK, but will directly invoke the varags version. This will cause a generic array to be created, and cause a warning. (This warning is suppressed in the 2-args-version, obviously).

    So to summarize, I assume that this is in order to avoid warnings for clients of the library who want to invoke the of method with several objects of a generic type.

    Fortunately, things like this will no longer be necessary in the future, thanks to http://docs.oracle.com/javase/7/docs/api/java/lang/SafeVarargs.html