What methods should go into a java.util.Objects class in JDK 7?

Martin Buchholz martinrb at google.com
Wed Oct 7 04:33:21 UTC 2009


I also vote against Objects.toString().
Foo.valueOf might not be the best name,
(I'll resist the urge to suggest a better one)
but it is an entrenched convention,
and so cannot be considered a wart to be fixed.

Martin

On Tue, Oct 6, 2009 at 20:14, David Holmes - Sun Microsystems
<David.Holmes at sun.com> wrote:
> Joe,
>
> Joe Darcy said the following on 10/07/09 09:43:
>>
>> David Holmes - Sun Microsystems wrote:
>>>
>>> I thought the point that Jason Mehrens was making was that this:
>>>
>>> +    public static String toString(Object o) {
>>> +        String.valueOf(o); hat Jason Mehrens was making was that this:
>>>
>>> +    public static String toString(Object o) {
>>> +        String.valueOf(o);
>>> +    }
>>>
>>> is actually pointless. Why introduce
>>> +    }
>>>
>>> is actually pointless. Why introduce such redundancy when people can just
>>> use String.valueOf directly ?
>>
>> Because, IMO, String.valueOf is obscure and hard to find and from its name
>> it is not clear it does null-safe toString on the argument.  For example, I
>> didn't know about String.valueOf.  It is much clearer what Objects.toString
>> is intended to do.
>
> It is no more obscure or hard to find than any method one is unaware of. But
> if you look at any of a number of introductory Java texts - such as The Java
> Programming Language for example - you will find that valueOf is given good
> coverage along with the other members of the String class. Further, as David
> Lloyd points out, there is a strong convention that Type.valueOf(x) converts
> x to Type - so the Java programmer should be quite familiar with this
> concept.
>
> I agree the null behaviour is not evident from the name, but nor is it
> evident from the name toString either - in both cases you must initially
> check the specification of the method to know what it does.
>
>>> This doesn't provide any benefit.
>>
>> I think having the new method be commonly called would be a benefit :-)
>
> No more so than having String.valueOf commonly called.
>
>> I don't think having a one-line forwarding method in Objects is that
>> harmful.
>
> It is redundant and adds no value. It creates potential confusion because
> people will wonder why on earth you have two methods that do the exact same
> thing. (And it's a PITA for authors because it is yet another additional API
> they have to mention. ;-) )
>
> Just my opinion of course.
>
> David
> -----
>>>
>>> PS. It should be "return String.valueOf(o);" of course.
>>
>> Fixed.
>>
>> Thanks,
>>
>> -Joe
>>
>>>
>>> David Holmes
>>>
>>> Joe Darcy said the following on 10/07/09 08:50:
>>>>
>>>> Joe Darcy wrote:
>>>>>
>>>>> Joe Darcy wrote:
>>>>>>
>>>>>> Joe Darcy wrote:
>>>>>>>
>>>>>>> Stephen Colebourne wrote:
>>>>>>>>
>>>>>>>> Joe Darcy wrote:
>>>>>>>>>
>>>>>>>>> What other utility methods would have broad enough use and
>>>>>>>>> applicability to go into a common java.util class?
>>>>>>>>
>>>>>>>> Joe,
>>>>>>>> You've asked for a call for ideas, but not given any indication of
>>>>>>>> process. Are you going to evaluate everything that comes in and pick the
>>>>>>>> best a la Coin? Or allow anyone to send in patches?
>>>>>>>
>>>>>>> Those options are not mutually exclusive; patches are welcome subject
>>>>>>> to the usual terms and conditions.
>>>>>>>
>>>>>>>> Who decides what is in and what is out?
>>>>>>>
>>>>>>> This is a little side project of mine and I wanted to get some
>>>>>>> feedback before preparing a formal change for review, possibly including
>>>>>>> patches from others.
>>>>>>>
>>>>>>> -Joe
>>>>>>
>>>>>> I'm getting caught up after the JVM Languages Summit and will post
>>>>>> some java.util.Objects code for review in the near future.
>>>>>>
>>>>>> -Joe
>>>>>
>>>>> Below is a patch implementing the methods I think should go into
>>>>> java.util.Objects as a first cut:
>>>>>
>>>>> * null safe two-argument equals method
>>>>> * null safe hashCode(Object) returning 0 for null
>>>>> * null safe toString(Object), returning "null" for a null argument
>>>>> * null tolerating compare method; tests if both arguments are == and if
>>>>> not calls compare
>>>>>
>>>>> The need for the last of these in Objects isn't quite as clear.
>>>>>
>>>>> Var-arg-ifying some of the existing methods in Arrays,
>>>>> (hashCode(Object[]), deepHashCode(Object[]) and toString(Object[])), is
>>>>> probably worthwhile but can be done separately.
>>>>>
>>>>> I wouldn't oppose a toDebugString(Object) method going into the
>>>>> platform somewhere, but I don't think it necessarily belongs in Objects.
>>>>>
>>>>> Further below is the code for an annotation processor which finds
>>>>> candidate equals methods to be replaced with Objects.equals.  It found over
>>>>> half a dozen good candidates in the jdk repository.  To run the annotation
>>>>> processor, first compile the class and then run it with javac similar to
>>>>> this:
>>>>>
>>>>> javac -proc:only -processor EqualsFinder -processorpath <path to
>>>>> processor> sources
>>>>>
>>>>> -Joe
>>>>>
>>>>
>>>> Updated patch of java.util.Objects with some spec clarifications
>>>> suggested by Alan Bateman and the use of and reference to
>>>> String.valueOf(Object) observed by Jason Mehrens.
>>>>
>>>> -Joe
>>>>
>>>>
>>>> --- /dev/null    2009-08-12 17:12:33.000000000 -0700
>>>> +++ new/src/share/classes/java/util/Objects.java    2009-10-06
>>>> 15:47:16.000000000 -0700
>>>> @@ -0,0 +1,100 @@
>>>> +/*
>>>> + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>> + *
>>>> + * This code is free software; you can redistribute it and/or modify it
>>>> + * under the terms of the GNU General Public License version 2 only, as
>>>> + * published by the Free Software Foundation.  Sun designates this
>>>> + * particular file as subject to the "Classpath" exception as provided
>>>> + * by Sun in the LICENSE file that accompanied this code.
>>>> + *
>>>> + * This code is distributed in the hope that it will be useful, but
>>>> WITHOUT
>>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
>>>> or
>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
>>>> License
>>>> + * version 2 for more details (a copy is included in the LICENSE file
>>>> that
>>>> + * accompanied this code).
>>>> + *
>>>> + * You should have received a copy of the GNU General Public License
>>>> version
>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>>>> + *
>>>> + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
>>>> Clara,
>>>> + * CA 95054 USA or visit www.sun.com if you need additional information
>>>> or
>>>> + * have any questions.
>>>> + */
>>>> +
>>>> +package java.util;
>>>> +
>>>> +/**
>>>> + * This class consists of {@code static} utility methods for operating
>>>> + * on objects.
>>>> + *
>>>> + * @since 1.7
>>>> + */
>>>> +public class Objects {
>>>> +    private Objects() {
>>>> +        throw new AssertionError("No java.util.Objects instances for
>>>> you!");
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Returns {@code true} if the arguments are equal to each other
>>>> +     * and {@code false} otherwise.
>>>> +     * Consequently, if both arguments are {@code null}, {@code true}
>>>> +     * is returned and if exactly one argument is {@code null}, {@code
>>>> +     * false} is returned.  Otherwise, equality is determined by using
>>>> +     * the {@link Object#equals equals} method of the first
>>>> +     * argument.
>>>> +     *
>>>> +     * @return {@code true} if the arguments are equal to each other
>>>> +     * and {@code false} otherwise
>>>> +     * @see Object#equals(Object)
>>>> +     */
>>>> +    public static boolean equals(Object a, Object b) {
>>>> +        return (a == b) || (a != null && a.equals(b));
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Returns the hash code of a non-{@code null} argument and 0 for
>>>> +     * a {@code null} argument.
>>>> +     *
>>>> +     * @return the hash code of a non-{@code null} argument and 0 for
>>>> +     * a {@code null} argument
>>>> +     * @see Object#hashCode
>>>> +     */
>>>> +    public static int hashCode(Object o) {
>>>> +        return o != null ? o.hashCode() : 0;
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Returns the result of calling {@code toString} for a non-{@code
>>>> +     * null} argument and {@code "null"} for a {@code null} argument.
>>>> +     *
>>>> +     * @return the result of calling {@code toString} for a non-{@code
>>>> +     * null} argument and {@code "null"} for a {@code null} argument
>>>> +     * @see Object#toString
>>>> +     * @see String#valueOf(Object)
>>>> +     */
>>>> +    public static String toString(Object o) {
>>>> +        String.valueOf(o);
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Returns 0 if the arguments are identical and {@code
>>>> +     * c.compare(a, b)} otherwise.
>>>> +     * Consequently, if both arguments are {@code null} 0
>>>> +     * is returned.
>>>> +     *
>>>> +     * <p>Note that if one of the argument is {@code null}, a {@code
>>>> +     * NullPointerException} may or may not be thrown depending on
>>>> +     * what ordering policy, if any, the {@link Comparator Comparator}
>>>> +     * chooses to have for {@code null} values.
>>>> +     *
>>>> +     * @return 0 if the arguments are identical and {@code
>>>> +     * c.compare(a, b)} otherwise.
>>>> +     * @see Comparable
>>>> +     * @see Comparator
>>>> +     */
>>>> +    public static <T> int compare(T a, T b, Comparator<? super T> c) {
>>>> +        return (a == b) ? 0 :  c.compare(a, b);
>>>> +    }
>>>> +}
>>
>



More information about the core-libs-dev mailing list