">

(original) (raw)

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 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;

+ � �}


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\[\])}.
�� � \*

�� � \*

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:
�� � \*
�� � \* @Override public int hashCode() {
�� � \* � � return Objects.hashCode(x, y, z);
�� � \* }
�� � \*
�� � \* Warning: When a single object reference is supplied, the returned
�� � \* value does not equal the hash code of that object reference. 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 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) {

+ � � � �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.
\+ � � \*
\+ � � \*

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 int compare(T a, T b, Comparator c) {
\+ � � � �return (a == b) ? 0 : �c.compare(a, b);
\+ � �}
+}

I don't think you should add this method (�compare(T a, T b, Comparator 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:
�� � \*
�� � \* public Foo(Bar bar) {
�� � \* � � this.bar = Objects.nonNull(bar);
�� � \* }
�� � \*
�� � \*
�� � \* @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 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:
�� � \*
�� � \* 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");
�� � \* }
�� � \*
�� � \*
�� � \* @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 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