Joe,
Hi.  I think it's great that you're doing this.  A few comments:

> +public class Objects {
> +    private Objects() {
> +        throw new AssertionError("No java.util.Objects instances for
> you!");
> +    }
>
Cute!


> +
> +    /**
> +     * 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));
> +    }
>
Very useful!  We've needed this one  ( equals(Object a, Object b) ) for
years.

+
> +    /**
> +     * 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;
> +    }
>

Again, very useful.  Along these lines, I would add this method too:

    /**
     * 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>
     * &#064;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);
    }

People still don't know how to hash objects with multiple fields; this
little method makes it much easier.


> +
> +    /**
> +     * 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) {
> +        return String.valueOf(o);
> +    }

I would definitely *not* add this method  (Objects.toString).  It brings
nothing to the table that isn't already there.  People know and use
String.valueOf.  Let's not muddy the waters by adding another choice.


> +
> +    /**
> +     * 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 arguments 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);
> +    }
> +}

I don't think you should add this method ( compare(T a, T b, Comparator<?
super T> c)).  Its utility is unclear, and it doesn't have the
power-to-weight ratio of the other methods in this class.

I strongly suggest that you do add these two methods:

    /**
     * Checks that the specified object reference is not {...@code null}. This
     * method is designed primarily for doing parameter validation in
methods
     * and constructors, as demonstrated below:
     * <pre>
     * public Foo(Bar bar) {
     *     this.bar = Objects.nonNull(bar);
     * }
     * </pre>
     *
     * @param obj the object reference to check for nullity
     * @return {...@code obj} if not {...@code null}
     * @throws NullPointerException if {...@code obj} is {...@code null}
     */
    public static <T> T nonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

    /**
     * Checks that the specified object reference is not {...@code null} and
     * throws a customized {...@link NullPointerException} if it is. This
method
     * is designed primarily for doing parameter validation in methods and
     * constructors with multiple parameters, as demonstrated below:
     * <pre>
     * public Foo(Bar bar, Baz baz) {
     *     this.bar = Objects.nonNull(bar, "bar must not be null");
     *     this.baz = Objects.nonNull(baz, "baz must not be null");
     * }
     * </pre>
     *
     * @param obj     the object reference to check for nullity
     * @param message detail message to be used in the event that a {...@code
     *                NullPointerException} is thrown
     * @return {...@code obj} if not {...@code null}
     * @throws NullPointerException if {...@code obj} is {...@code null}
     */
    public static <T> T nonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }

They do a great job reducing the verbiage in validity-checking of arguments
that must not be null.

                Regards,

                Josh Bloch and Bob Lee

Reply via email to