j.ul.Objects follow-up: methods for var-argification?

Joshua Bloch jjb at google.com
Fri Oct 9 16:55:46 UTC 2009


Joe,

I'm not sure I like this idea.  My one experience with forcing an array
method to do double duty as varargs method was a disaster.  The method was
Arrays.asList, and the result was Puzzler # 7 from "The Continuing
Adventures of Java™Puzzlers: Tiger Traps."  Here it is:

*7. “Fib O’Nacci”*

public class Fibonacci {
    private static final int LENGTH = 7;
    public static void main(String[] args) {
        int[] fib = new int[LENGTH];
        fib[0] = fib[1] = 1; // First 2 Fibonacci numbers
        for (inti = 2; i < LENGTH; i++)
            fib[i] = fib[i -2] + fib[i -1];
        System.out.println(Arrays.asList(fib));
    }
}

The main moral of the puzzle was:

Use varargssparingly in your APIs
    •It can hide errors and cause confusion
    •This program wouldn't compile under 1.4

Arrays.hashCode, equals, and toString are already overloaded out the wazoo;
adding varargs to the mix could be deadly.  Also, Arrays is not the place
where people would go looking for what is essentially a hashing utility.  So
I'm not in favor of varargifying the existing methods in Arrays, but I am in
favor of adding a convenience method like this somewhere:

         /**
     * Generates a hash code for a sequence of input values. The hash code
is
     * generated as if all the input values were placed into an array, and
that
     * array were hashed by calling {@link Arrays#hashCode(Object[])}.
     * <p/>
     * <p>This method is useful for implementing {@link Object#hashCode()}
on
     * objects containing multiple fields. For example, if an object that
has
     * three  fields, {@code x}, {@code y}, and {@code z}, one could write:
     * <pre>
     * @Override public int hashCode() {
     *     return Objects.hashCode(x, y, z);
     * }
     * </pre>
     * <b>Warning: When a single object reference is supplied, the returned
     * value does not equal the hash code of that object reference.</b> This
     * value can be computed by calling {@link #hashCode(Object)}.
     */
    public static int hash(Object... components) {
        return Arrays.hashCode(components);
    }

Viewed in isolation, it's simple, straightforward, and will help people
write high quality hashCode methods.  I don't think Objects is a bad place
for it, but you could put it is a "hash utility" class if we wrote such a
thing.

          Josh


On Thu, Oct 8, 2009 at 11:34 AM, Joseph D. Darcy <Joe.Darcy at sun.com> wrote:

> Hello.
>
> In the discussion about java.util.Objects, a few existing JDK methods were
> mentioned for possible var-argification:
>
> java.util.Arrays.hashCode(Object[] a)
> java.util.Arrays.deepHashCode(Object[] a)
> java.util.Arrays.toString(Object[] a)
>
> Also of possible general interest are some methods on String (bug 6762452
> API change proposal: Enhance String constructor for varargs)
>
> java.lang.String.copyValueOf(char[] data)
> java.lang.String.valueOf(char[] data)
> java.lang.String(char[] value)
>
> Var-argification is fully binary compatible and is generally source
> compatible, although new conversions are allowed of course and overloadings
> may change.
>
> -Joe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/core-libs-dev/attachments/20091009/27b1dc5d/attachment.html>


More information about the core-libs-dev mailing list