git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1077992 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2011-03-04 15:08:53 +00:00
parent c21a7a26c0
commit 81b5d12e81
1 changed files with 94 additions and 95 deletions

View File

@ -24,10 +24,10 @@ import java.lang.reflect.Method;
import org.apache.commons.lang3.exception.CloneFailedException; import org.apache.commons.lang3.exception.CloneFailedException;
/** /**
* <p>Operations on <code>Object</code>.</p> * <p>Operations on {@code Object}.</p>
* *
* <p>This class tries to handle <code>null</code> input gracefully. * <p>This class tries to handle {@code null} input gracefully.
* An exception will generally not be thrown for a <code>null</code> input. * An exception will generally not be thrown for a {@code null} input.
* Each method documents its behaviour in more detail.</p> * Each method documents its behaviour in more detail.</p>
* *
* <p>#ThreadSafe#</p> * <p>#ThreadSafe#</p>
@ -45,17 +45,16 @@ import org.apache.commons.lang3.exception.CloneFailedException;
public class ObjectUtils { public class ObjectUtils {
/** /**
* <p>Singleton used as a <code>null</code> placeholder where * <p>Singleton used as a {@code null} placeholder where
* <code>null</code> has another meaning.</p> * {@code null} has another meaning.</p>
* *
* <p>For example, in a <code>HashMap</code> the * <p>For example, in a {@code HashMap} the
* {@link java.util.HashMap#get(java.lang.Object)} method returns * {@link java.util.HashMap#get(java.lang.Object)} method returns
* <code>null</code> if the <code>Map</code> contains * {@code null} if the {@code Map} contains {@code null} or if there
* <code>null</code> or if there is no matching key. The * is no matching key. The {@code Null} placeholder can be used to
* <code>Null</code> placeholder can be used to distinguish between * distinguish between these two cases.</p>
* these two cases.</p>
* *
* <p>Another example is <code>Hashtable</code>, where <code>null</code> * <p>Another example is {@code Hashtable}, where {@code null}
* cannot be stored.</p> * cannot be stored.</p>
* *
* <p>This instance is Serializable.</p> * <p>This instance is Serializable.</p>
@ -63,12 +62,12 @@ public class ObjectUtils {
public static final Null NULL = new Null(); public static final Null NULL = new Null();
/** /**
* <p><code>ObjectUtils</code> instances should NOT be constructed in * <p>{@code ObjectUtils} instances should NOT be constructed in
* standard programming. Instead, the class should be used as * standard programming. Instead, the static methods on the class should
* <code>ObjectUtils.defaultIfNull("a","b");</code>.</p> * be used, such as {@code ObjectUtils.defaultIfNull("a","b");}.</p>
* *
* <p>This constructor is public to permit tools that require a JavaBean instance * <p>This constructor is public to permit tools that require a JavaBean
* to operate.</p> * instance to operate.</p>
*/ */
public ObjectUtils() { public ObjectUtils() {
super(); super();
@ -77,8 +76,7 @@ public class ObjectUtils {
// Defaulting // Defaulting
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* <p>Returns a default value if the object passed is * <p>Returns a default value if the object passed is {@code null}.</p>
* <code>null</code>.</p>
* *
* <pre> * <pre>
* ObjectUtils.defaultIfNull(null, null) = null * ObjectUtils.defaultIfNull(null, null) = null
@ -88,18 +86,18 @@ public class ObjectUtils {
* ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
* </pre> * </pre>
* *
* @param object the <code>Object</code> to test, may be <code>null</code> * @param object the {@code Object} to test, may be {@code null}
* @param defaultValue the default value to return, may be <code>null</code> * @param defaultValue the default value to return, may be {@code null}
* @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise * @return {@code object} if it is not {@code null}, defaultValue otherwise
*/ */
public static <T> T defaultIfNull(T object, T defaultValue) { public static <T> T defaultIfNull(T object, T defaultValue) {
return object != null ? object : defaultValue; return object != null ? object : defaultValue;
} }
/** /**
* <p>Returns the first value in the array which is not <code>null</code>. * <p>Returns the first value in the array which is not {@code null}.
* If all the values are <code>null</code> or the array is <code>null</code> * If all the values are {@code null} or the array is {@code null}
* or empty then <code>null</code> is returned.</p> * or empty then {@code null} is returned.</p>
* *
* <pre> * <pre>
* ObjectUtils.firstNonNull(null, null) = null * ObjectUtils.firstNonNull(null, null) = null
@ -112,9 +110,9 @@ public class ObjectUtils {
* ObjectUtils.firstNonNull() = null * ObjectUtils.firstNonNull() = null
* </pre> * </pre>
* *
* @param values the values to test, may be <code>null</code> or empty * @param values the values to test, may be {@code null} or empty
* @return the first value from <code>values</code> which is not <code>null</code>, * @return the first value from {@code values} which is not {@code null},
* or <code>null</code> if there are no non-null values * or {@code null} if there are no non-null values
*/ */
public static <T> T firstNonNull(T... values) { public static <T> T firstNonNull(T... values) {
if (values != null) { if (values != null) {
@ -131,7 +129,7 @@ public class ObjectUtils {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* <p>Compares two objects for equality, where either one or both * <p>Compares two objects for equality, where either one or both
* objects may be <code>null</code>.</p> * objects may be {@code null}.</p>
* *
* <pre> * <pre>
* ObjectUtils.equals(null, null) = true * ObjectUtils.equals(null, null) = true
@ -144,9 +142,9 @@ public class ObjectUtils {
* ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
* </pre> * </pre>
* *
* @param object1 the first object, may be <code>null</code> * @param object1 the first object, may be {@code null}
* @param object2 the second object, may be <code>null</code> * @param object2 the second object, may be {@code null}
* @return <code>true</code> if the values of both objects are the same * @return {@code true} if the values of both objects are the same
*/ */
public static boolean equals(Object object1, Object object2) { public static boolean equals(Object object1, Object object2) {
if (object1 == object2) { if (object1 == object2) {
@ -160,7 +158,7 @@ public class ObjectUtils {
/** /**
* <p>Compares two objects for inequality, where either one or both * <p>Compares two objects for inequality, where either one or both
* objects may be <code>null</code>.</p> * objects may be {@code null}.</p>
* *
* <pre> * <pre>
* ObjectUtils.notEqual(null, null) = false * ObjectUtils.notEqual(null, null) = false
@ -173,9 +171,9 @@ public class ObjectUtils {
* ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true * ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true
* </pre> * </pre>
* *
* @param object1 the first object, may be <code>null</code> * @param object1 the first object, may be {@code null}
* @param object2 the second object, may be <code>null</code> * @param object2 the second object, may be {@code null}
* @return <code>false</code> if the values of both objects are the same * @return {@code false} if the values of both objects are the same
*/ */
public static boolean notEqual(Object object1, Object object2) { public static boolean notEqual(Object object1, Object object2) {
return ObjectUtils.equals(object1, object2) == false; return ObjectUtils.equals(object1, object2) == false;
@ -183,14 +181,14 @@ public class ObjectUtils {
/** /**
* <p>Gets the hash code of an object returning zero when the * <p>Gets the hash code of an object returning zero when the
* object is <code>null</code>.</p> * object is {@code null}.</p>
* *
* <pre> * <pre>
* ObjectUtils.hashCode(null) = 0 * ObjectUtils.hashCode(null) = 0
* ObjectUtils.hashCode(obj) = obj.hashCode() * ObjectUtils.hashCode(obj) = obj.hashCode()
* </pre> * </pre>
* *
* @param obj the object to obtain the hash code of, may be <code>null</code> * @param obj the object to obtain the hash code of, may be {@code null}
* @return the hash code of the object, or zero if null * @return the hash code of the object, or zero if null
* @since 2.1 * @since 2.1
*/ */
@ -201,9 +199,9 @@ public class ObjectUtils {
// Identity ToString // Identity ToString
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* <p>Gets the toString that would be produced by <code>Object</code> * <p>Gets the toString that would be produced by {@code Object}
* if a class did not override toString itself. <code>null</code> * if a class did not override toString itself. {@code null}
* will return <code>null</code>.</p> * will return {@code null}.</p>
* *
* <pre> * <pre>
* ObjectUtils.identityToString(null) = null * ObjectUtils.identityToString(null) = null
@ -212,9 +210,9 @@ public class ObjectUtils {
* </pre> * </pre>
* *
* @param object the object to create a toString for, may be * @param object the object to create a toString for, may be
* <code>null</code> * {@code null}
* @return the default toString text, or <code>null</code> if * @return the default toString text, or {@code null} if
* <code>null</code> passed in * {@code null} passed in
*/ */
public static String identityToString(Object object) { public static String identityToString(Object object) {
if (object == null) { if (object == null) {
@ -226,8 +224,8 @@ public class ObjectUtils {
} }
/** /**
* <p>Appends the toString that would be produced by <code>Object</code> * <p>Appends the toString that would be produced by {@code Object}
* if a class did not override toString itself. <code>null</code> * if a class did not override toString itself. {@code null}
* will throw a NullPointerException for either of the two parameters. </p> * will throw a NullPointerException for either of the two parameters. </p>
* *
* <pre> * <pre>
@ -252,8 +250,8 @@ public class ObjectUtils {
// ToString // ToString
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* <p>Gets the <code>toString</code> of an <code>Object</code> returning * <p>Gets the {@code toString} of an {@code Object} returning
* an empty string ("") if <code>null</code> input.</p> * an empty string ("") if {@code null} input.</p>
* *
* <pre> * <pre>
* ObjectUtils.toString(null) = "" * ObjectUtils.toString(null) = ""
@ -264,8 +262,8 @@ public class ObjectUtils {
* *
* @see StringUtils#defaultString(String) * @see StringUtils#defaultString(String)
* @see String#valueOf(Object) * @see String#valueOf(Object)
* @param obj the Object to <code>toString</code>, may be null * @param obj the Object to {@code toString}, may be null
* @return the passed in Object's toString, or nullStr if <code>null</code> input * @return the passed in Object's toString, or nullStr if {@code null} input
* @since 2.0 * @since 2.0
*/ */
public static String toString(Object obj) { public static String toString(Object obj) {
@ -273,8 +271,8 @@ public class ObjectUtils {
} }
/** /**
* <p>Gets the <code>toString</code> of an <code>Object</code> returning * <p>Gets the {@code toString} of an {@code Object} returning
* a specified text if <code>null</code> input.</p> * a specified text if {@code null} input.</p>
* *
* <pre> * <pre>
* ObjectUtils.toString(null, null) = null * ObjectUtils.toString(null, null) = null
@ -286,9 +284,9 @@ public class ObjectUtils {
* *
* @see StringUtils#defaultString(String,String) * @see StringUtils#defaultString(String,String)
* @see String#valueOf(Object) * @see String#valueOf(Object)
* @param obj the Object to <code>toString</code>, may be null * @param obj the Object to {@code toString}, may be null
* @param nullStr the String to return if <code>null</code> input, may be null * @param nullStr the String to return if {@code null} input, may be null
* @return the passed in Object's toString, or nullStr if <code>null</code> input * @return the passed in Object's toString, or nullStr if {@code null} input
* @since 2.0 * @since 2.0
*/ */
public static String toString(Object obj, String nullStr) { public static String toString(Object obj, String nullStr) {
@ -298,14 +296,14 @@ public class ObjectUtils {
// Min/Max // Min/Max
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* Null safe comparison of Comparables. * <p>Null safe comparison of Comparables.</p>
* *
* @param values the set of comparable values, may be null * @param values the set of comparable values, may be null
* @return * @return
* <ul> * <ul>
* <li>If any objects are non-null and unequal, the lesser object. * <li>If any objects are non-null and unequal, the lesser object.
* <li>If all objects are non-null and equal, the first. * <li>If all objects are non-null and equal, the first.
* <li>If any of the comparables are null, the lesser of the non-null object. * <li>If any of the comparables are null, the lesser of the non-null objects.
* <li>If all the comparables are null, null is returned. * <li>If all the comparables are null, null is returned.
* </ul> * </ul>
*/ */
@ -322,14 +320,14 @@ public class ObjectUtils {
} }
/** /**
* Null safe comparison of Comparables. * <p>Null safe comparison of Comparables.</p>
* *
* @param values the set of comparable values, may be null * @param values the set of comparable values, may be null
* @return * @return
* <ul> * <ul>
* <li>If any objects are non-null and unequal, the greater object. * <li>If any objects are non-null and unequal, the greater object.
* <li>If all objects are non-null and equal, the first. * <li>If all objects are non-null and equal, the first.
* <li>If any of the comparables are null, the greater of the non-null object. * <li>If any of the comparables are null, the greater of the non-null objects.
* <li>If all the comparables are null, null is returned. * <li>If all the comparables are null, null is returned.
* </ul> * </ul>
*/ */
@ -346,28 +344,28 @@ public class ObjectUtils {
} }
/** /**
* Null safe comparison of Comparables. * <p>Null safe comparison of Comparables.
* {@code null} is assumed to be less than a non-{@code null} value. * {@code null} is assumed to be less than a non-{@code null} value.</p>
* *
* @param c1 the first comparable, may be null * @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null * @param c2 the second comparable, may be null
* @return a negative value if c1 < c2, zero if c1 = c2 * @return a negative value if c1 < c2, zero if c1 = c2
* and a positive value if c1 > c2 * and a positive value if c1 > c2
*/ */
public static <T extends Comparable<? super T>> int compare(T c1, T c2) { public static <T extends Comparable<? super T>> int compare(T c1, T c2) {
return compare(c1, c2, false); return compare(c1, c2, false);
} }
/** /**
* Null safe comparison of Comparables. * <p>Null safe comparison of Comparables.</p>
* *
* @param c1 the first comparable, may be null * @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null * @param c2 the second comparable, may be null
* @param nullGreater if true <code>null</code> is considered greater * @param nullGreater if true {@code null} is considered greater
* than a Non-<code>null</code> value or if false <code>null</code> is * than a non-{@code null} value or if false {@code null} is
* considered less than a Non-<code>null</code> value * considered less than a Non-{@code null} value
* @return a negative value if c1 < c2, zero if c1 = c2 * @return a negative value if c1 < c2, zero if c1 = c2
* and a positive value if c1 > c2 * and a positive value if c1 > c2
* @see java.util.Comparator#compare(Object, Object) * @see java.util.Comparator#compare(Object, Object)
*/ */
public static <T extends Comparable<? super T>> int compare(T c1, T c2, boolean nullGreater) { public static <T extends Comparable<? super T>> int compare(T c1, T c2, boolean nullGreater) {
@ -382,42 +380,42 @@ public class ObjectUtils {
} }
/** /**
* Clone an object. * <p>Clone an object.</p>
* *
* @param <T> the type of the object * @param <T> the type of the object
* @param o the object to clone * @param obj the object to clone, null returns null
* @return the clone if the object implements {@link Cloneable} otherwise <code>null</code> * @return the clone if the object implements {@link Cloneable} otherwise {@code null}
* @throws CloneFailedException if the object is cloneable and the clone operation fails * @throws CloneFailedException if the object is cloneable and the clone operation fails
* @since 3.0 * @since 3.0
*/ */
public static <T> T clone(final T o) { public static <T> T clone(final T obj) {
if (o instanceof Cloneable) { if (obj instanceof Cloneable) {
final Object result; final Object result;
if (o.getClass().isArray()) { if (obj.getClass().isArray()) {
final Class<?> componentType = o.getClass().getComponentType(); final Class<?> componentType = obj.getClass().getComponentType();
if (!componentType.isPrimitive()) { if (!componentType.isPrimitive()) {
result = ((Object[]) o).clone(); result = ((Object[]) obj).clone();
} else { } else {
int length = Array.getLength(o); int length = Array.getLength(obj);
result = Array.newInstance(componentType, length); result = Array.newInstance(componentType, length);
while (length-- > 0) { while (length-- > 0) {
Array.set(result, length, Array.get(o, length)); Array.set(result, length, Array.get(obj, length));
} }
} }
} else { } else {
try { try {
final Method clone = o.getClass().getMethod("clone"); final Method clone = obj.getClass().getMethod("clone");
result = clone.invoke(o); result = clone.invoke(obj);
} catch (final NoSuchMethodException e) { } catch (final NoSuchMethodException e) {
throw new CloneFailedException("Cloneable type " throw new CloneFailedException("Cloneable type "
+ o.getClass().getName() + obj.getClass().getName()
+ " has no clone method", e); + " has no clone method", e);
} catch (final IllegalAccessException e) { } catch (final IllegalAccessException e) {
throw new CloneFailedException("Cannot clone Cloneable type " throw new CloneFailedException("Cannot clone Cloneable type "
+ o.getClass().getName(), e); + obj.getClass().getName(), e);
} catch (final InvocationTargetException e) { } catch (final InvocationTargetException e) {
throw new CloneFailedException("Exception cloning Cloneable type " throw new CloneFailedException("Exception cloning Cloneable type "
+ o.getClass().getName(), e.getCause()); + obj.getClass().getName(), e.getCause());
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -429,38 +427,39 @@ public class ObjectUtils {
} }
/** /**
* Clone an object if possible. This method is similar to {@link #clone(Object)}, but will * <p>Clone an object if possible.</p>
* return the provided instance as the return value instead of <code>null</code> if the instance *
* <p>This method is similar to {@link #clone(Object)}, but will return the provided
* instance as the return value instead of {@code null} if the instance
* is not cloneable. This is more convenient if the caller uses different * is not cloneable. This is more convenient if the caller uses different
* implementations (e.g. of a service) and some of the implementations do not allow concurrent * implementations (e.g. of a service) and some of the implementations do not allow concurrent
* processing or have state. In such cases the implementation can simply provide a proper * processing or have state. In such cases the implementation can simply provide a proper
* clone implementation and the caller's code does not have to change. * clone implementation and the caller's code does not have to change.</p>
* *
* @param <T> the type of the object * @param <T> the type of the object
* @param o the object to clone * @param obj the object to clone, null returns null
* @return the clone if the object implements {@link Cloneable} otherwise the object itself * @return the clone if the object implements {@link Cloneable} otherwise the object itself
* @throws CloneFailedException if the object is cloneable and the clone operation fails * @throws CloneFailedException if the object is cloneable and the clone operation fails
* @since 3.0 * @since 3.0
*/ */
public static <T> T cloneIfPossible(final T o) { public static <T> T cloneIfPossible(final T obj) {
final T clone = clone(o); final T clone = clone(obj);
return clone == null ? o : clone; return clone == null ? obj : clone;
} }
// Null // Null
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** /**
* <p>Class used as a null placeholder where <code>null</code> * <p>Class used as a null placeholder where {@code null}
* has another meaning.</p> * has another meaning.</p>
* *
* <p>For example, in a <code>HashMap</code> the * <p>For example, in a {@code HashMap} the
* {@link java.util.HashMap#get(java.lang.Object)} method returns * {@link java.util.HashMap#get(java.lang.Object)} method returns
* <code>null</code> if the <code>Map</code> contains * {@code null} if the {@code Map} contains {@code null} or if there is
* <code>null</code> or if there is no matching key. The * no matching key. The {@code Null} placeholder can be used to distinguish
* <code>Null</code> placeholder can be used to distinguish between * between these two cases.</p>
* these two cases.</p>
* *
* <p>Another example is <code>Hashtable</code>, where <code>null</code> * <p>Another example is {@code Hashtable}, where {@code null}
* cannot be stored.</p> * cannot be stored.</p>
*/ */
public static class Null implements Serializable { public static class Null implements Serializable {