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

Rémi Forax forax at univ-mlv.fr
Mon Oct 12 19:52:39 UTC 2009


Le 12/10/2009 20:41, Joseph D. Darcy a écrit :
> Rémi Forax wrote:
>> Le 12/10/2009 19:25, Joseph D. Darcy a écrit :
>>> Joshua Bloch wrote:
>>>> 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.
>>>>
>>>
>>> Okay; unless and until a hash utility is added somewhere, this 
>>> hash(Object ...) can live in Objects.
>>>
>>> -Joe
>>
>> In that case, we can also add some methods hash that avoid create an 
>> array
>> for let say 2 to 5 arguments:
>> hash(Object, Object), hash-Object, Object, Object), 
>> hash(Object,Object,Object,Object)
>> and hash(Object,Object,Object,Object,Object).
>>
>
> I don't think such methods are justified at present.
>
> -Joe
>

It's not a good idea to have a hashCode() that allocate objects,
at least until escape analysis is implemented in all VMs.

Rémi





More information about the core-libs-dev mailing list