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.hol...@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 no...@code null} argument and 0 for >>>> + * a {...@code null} argument. >>>> + * >>>> + * @return the hash code of a no...@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 no...@code >>>> + * null} argument and {...@code "null"} for a {...@code null} >>>> argument. >>>> + * >>>> + * @return the result of calling {...@code toString} for a no...@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); >>>> + } >>>> +} >> >