001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.lang3;
018
019 import java.io.Serializable;
020 import java.lang.reflect.Array;
021 import java.lang.reflect.InvocationTargetException;
022 import java.lang.reflect.Method;
023
024 import org.apache.commons.lang3.exception.CloneFailedException;
025
026 /**
027 * <p>Operations on <code>Object</code>.</p>
028 *
029 * <p>This class tries to handle <code>null</code> input gracefully.
030 * An exception will generally not be thrown for a <code>null</code> input.
031 * Each method documents its behaviour in more detail.</p>
032 *
033 * <p>#ThreadSafe#</p>
034 * @author Apache Software Foundation
035 * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
036 * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
037 * @author Daniel L. Rall
038 * @author Gary Gregory
039 * @author Mario Winterer
040 * @author <a href="mailto:david@davidkarlsen.com">David J. M. Karlsen</a>
041 * @since 1.0
042 * @version $Id: ObjectUtils.java 960138 2010-07-03 00:30:46Z joehni $
043 */
044 //@Immutable
045 public class ObjectUtils {
046
047 /**
048 * <p>Singleton used as a <code>null</code> placeholder where
049 * <code>null</code> has another meaning.</p>
050 *
051 * <p>For example, in a <code>HashMap</code> the
052 * {@link java.util.HashMap#get(java.lang.Object)} method returns
053 * <code>null</code> if the <code>Map</code> contains
054 * <code>null</code> or if there is no matching key. The
055 * <code>Null</code> placeholder can be used to distinguish between
056 * these two cases.</p>
057 *
058 * <p>Another example is <code>Hashtable</code>, where <code>null</code>
059 * cannot be stored.</p>
060 *
061 * <p>This instance is Serializable.</p>
062 */
063 public static final Null NULL = new Null();
064
065 /**
066 * <p><code>ObjectUtils</code> instances should NOT be constructed in
067 * standard programming. Instead, the class should be used as
068 * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p>
069 *
070 * <p>This constructor is public to permit tools that require a JavaBean instance
071 * to operate.</p>
072 */
073 public ObjectUtils() {
074 super();
075 }
076
077 // Defaulting
078 //-----------------------------------------------------------------------
079 /**
080 * <p>Returns a default value if the object passed is
081 * <code>null</code>.</p>
082 *
083 * <pre>
084 * ObjectUtils.defaultIfNull(null, null) = null
085 * ObjectUtils.defaultIfNull(null, "") = ""
086 * ObjectUtils.defaultIfNull(null, "zz") = "zz"
087 * ObjectUtils.defaultIfNull("abc", *) = "abc"
088 * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
089 * </pre>
090 *
091 * @param object the <code>Object</code> to test, may be <code>null</code>
092 * @param defaultValue the default value to return, may be <code>null</code>
093 * @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise
094 */
095 public static Object defaultIfNull(Object object, Object defaultValue) {
096 return object != null ? object : defaultValue;
097 }
098
099 /**
100 * <p>Returns the first value in the array which is not <code>null</code>.
101 * If all the values are <code>null</code> or the array is <code>null</code>
102 * or empty then <code>null</code> is returned.</p>
103 *
104 * <pre>
105 * ObjectUtils.firstNonNull(null, null) = null
106 * ObjectUtils.firstNonNull(null, "") = ""
107 * ObjectUtils.firstNonNull(null, null, "") = ""
108 * ObjectUtils.firstNonNull(null, "zz") = "zz"
109 * ObjectUtils.firstNonNull("abc", *) = "abc"
110 * ObjectUtils.firstNonNull(null, "xyz", *) = "xyz"
111 * ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE
112 * ObjectUtils.firstNonNull() = null
113 * </pre>
114 *
115 * @param values the values to test, may be <code>null</code> or empty
116 * @return the first value from <code>values</code> which is not <code>null</code>,
117 * or <code>null</code> if there are no non-null values
118 */
119 public static <T> T firstNonNull(T... values) {
120 if (values != null) {
121 for (T val : values) {
122 if (val != null) {
123 return val;
124 }
125 }
126 }
127 return null;
128 }
129
130 // Null-safe equals/hashCode
131 //-----------------------------------------------------------------------
132 /**
133 * <p>Compares two objects for equality, where either one or both
134 * objects may be <code>null</code>.</p>
135 *
136 * <pre>
137 * ObjectUtils.equals(null, null) = true
138 * ObjectUtils.equals(null, "") = false
139 * ObjectUtils.equals("", null) = false
140 * ObjectUtils.equals("", "") = true
141 * ObjectUtils.equals(Boolean.TRUE, null) = false
142 * ObjectUtils.equals(Boolean.TRUE, "true") = false
143 * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true
144 * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
145 * </pre>
146 *
147 * @param object1 the first object, may be <code>null</code>
148 * @param object2 the second object, may be <code>null</code>
149 * @return <code>true</code> if the values of both objects are the same
150 */
151 public static boolean equals(Object object1, Object object2) {
152 if (object1 == object2) {
153 return true;
154 }
155 if ((object1 == null) || (object2 == null)) {
156 return false;
157 }
158 return object1.equals(object2);
159 }
160
161 /**
162 * <p>Gets the hash code of an object returning zero when the
163 * object is <code>null</code>.</p>
164 *
165 * <pre>
166 * ObjectUtils.hashCode(null) = 0
167 * ObjectUtils.hashCode(obj) = obj.hashCode()
168 * </pre>
169 *
170 * @param obj the object to obtain the hash code of, may be <code>null</code>
171 * @return the hash code of the object, or zero if null
172 * @since 2.1
173 */
174 public static int hashCode(Object obj) {
175 return (obj == null) ? 0 : obj.hashCode();
176 }
177
178 // Identity ToString
179 //-----------------------------------------------------------------------
180 /**
181 * <p>Gets the toString that would be produced by <code>Object</code>
182 * if a class did not override toString itself. <code>null</code>
183 * will return <code>null</code>.</p>
184 *
185 * <pre>
186 * ObjectUtils.identityToString(null) = null
187 * ObjectUtils.identityToString("") = "java.lang.String@1e23"
188 * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
189 * </pre>
190 *
191 * @param object the object to create a toString for, may be
192 * <code>null</code>
193 * @return the default toString text, or <code>null</code> if
194 * <code>null</code> passed in
195 */
196 public static String identityToString(Object object) {
197 if (object == null) {
198 return null;
199 }
200 StringBuffer buffer = new StringBuffer();
201 identityToString(buffer, object);
202 return buffer.toString();
203 }
204
205 /**
206 * <p>Appends the toString that would be produced by <code>Object</code>
207 * if a class did not override toString itself. <code>null</code>
208 * will throw a NullPointerException for either of the two parameters. </p>
209 *
210 * <pre>
211 * ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23"
212 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa"
213 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
214 * </pre>
215 *
216 * @param buffer the buffer to append to
217 * @param object the object to create a toString for
218 * @since 2.4
219 */
220 public static void identityToString(StringBuffer buffer, Object object) {
221 if (object == null) {
222 throw new NullPointerException("Cannot get the toString of a null identity");
223 }
224 buffer.append(object.getClass().getName())
225 .append('@')
226 .append(Integer.toHexString(System.identityHashCode(object)));
227 }
228
229 // ToString
230 //-----------------------------------------------------------------------
231 /**
232 * <p>Gets the <code>toString</code> of an <code>Object</code> returning
233 * an empty string ("") if <code>null</code> input.</p>
234 *
235 * <pre>
236 * ObjectUtils.toString(null) = ""
237 * ObjectUtils.toString("") = ""
238 * ObjectUtils.toString("bat") = "bat"
239 * ObjectUtils.toString(Boolean.TRUE) = "true"
240 * </pre>
241 *
242 * @see StringUtils#defaultString(String)
243 * @see String#valueOf(Object)
244 * @param obj the Object to <code>toString</code>, may be null
245 * @return the passed in Object's toString, or nullStr if <code>null</code> input
246 * @since 2.0
247 */
248 public static String toString(Object obj) {
249 return obj == null ? "" : obj.toString();
250 }
251
252 /**
253 * <p>Gets the <code>toString</code> of an <code>Object</code> returning
254 * a specified text if <code>null</code> input.</p>
255 *
256 * <pre>
257 * ObjectUtils.toString(null, null) = null
258 * ObjectUtils.toString(null, "null") = "null"
259 * ObjectUtils.toString("", "null") = ""
260 * ObjectUtils.toString("bat", "null") = "bat"
261 * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
262 * </pre>
263 *
264 * @see StringUtils#defaultString(String,String)
265 * @see String#valueOf(Object)
266 * @param obj the Object to <code>toString</code>, may be null
267 * @param nullStr the String to return if <code>null</code> input, may be null
268 * @return the passed in Object's toString, or nullStr if <code>null</code> input
269 * @since 2.0
270 */
271 public static String toString(Object obj, String nullStr) {
272 return obj == null ? nullStr : obj.toString();
273 }
274
275 // Min/Max
276 //-----------------------------------------------------------------------
277 /**
278 * Null safe comparison of Comparables.
279 *
280 * @param c1 the first comparable, may be null
281 * @param c2 the second comparable, may be null
282 * @return
283 * <ul>
284 * <li>If both objects are non-null and unequal, the lesser object.
285 * <li>If both objects are non-null and equal, c1.
286 * <li>If one of the comparables is null, the non-null object.
287 * <li>If both the comparables are null, null is returned.
288 * </ul>
289 */
290 public static <T extends Comparable<? super T>> T min(T c1, T c2) {
291 if (c1 != null && c2 != null) {
292 return c1.compareTo(c2) < 1 ? c1 : c2;
293 } else {
294 return c1 != null ? c1 : c2;
295 }
296 }
297
298 /**
299 * Null safe comparison of Comparables.
300 *
301 * @param c1 the first comparable, may be null
302 * @param c2 the second comparable, may be null
303 * @return
304 * <ul>
305 * <li>If both objects are non-null and unequal, the greater object.
306 * <li>If both objects are non-null and equal, c1.
307 * <li>If one of the comparables is null, the non-null object.
308 * <li>If both the comparables are null, null is returned.
309 * </ul>
310 */
311 public static <T extends Comparable<? super T>> T max(T c1, T c2) {
312 if (c1 != null && c2 != null) {
313 return c1.compareTo(c2) >= 0 ? c1 : c2;
314 } else {
315 return c1 != null ? c1 : c2;
316 }
317 }
318
319 /**
320 * Clone an object.
321 *
322 * @param <T> the type of the object
323 * @param o the object to clone
324 * @return the clone if the object implements {@link Cloneable} otherwise <code>null</code>
325 * @throws CloneFailedException if the object is cloneable and the clone operation fails
326 * @since 3.0
327 */
328 public static <T> T clone(final T o) {
329 if (o instanceof Cloneable) {
330 final Object result;
331 if (o.getClass().isArray()) {
332 final Class<?> componentType = o.getClass().getComponentType();
333 if (!componentType.isPrimitive()) {
334 result = ((Object[])o).clone();
335 } else {
336 int length = Array.getLength(o);
337 result = Array.newInstance(componentType, length);
338 while (length-- > 0) {
339 Array.set(result, length, Array.get(o, length));
340 }
341 }
342 } else {
343 try {
344 final Method clone = o.getClass().getMethod("clone");
345 result = clone.invoke(o);
346 } catch (final NoSuchMethodException e) {
347 throw new CloneFailedException("Cloneable type "
348 + o.getClass().getName()
349 + " has no clone method", e);
350 } catch (final IllegalAccessException e) {
351 throw new CloneFailedException("Cannot clone Cloneable type "
352 + o.getClass().getName(), e);
353 } catch (final InvocationTargetException e) {
354 throw new CloneFailedException("Exception cloning Cloneable type "
355 + o.getClass().getName(), e.getCause());
356 }
357 }
358 @SuppressWarnings("unchecked")
359 final T checked = (T)result;
360 return checked;
361 }
362
363 return null;
364 }
365
366 /**
367 * Clone an object if possible. This method is similar to {@link #clone(Object)}, but will
368 * return the provided instance as the return value instead of <code>null</code> if the instance
369 * is not cloneable. This is more convenient if the caller uses different
370 * implementations (e.g. of a service) and some of the implementations do not allow concurrent
371 * processing or have state. In such cases the implementation can simply provide a proper
372 * clone implementation and the caller's code does not have to change.
373 *
374 * @param <T> the type of the object
375 * @param o the object to clone
376 * @return the clone if the object implements {@link Cloneable} otherwise the object itself
377 * @throws CloneFailedException if the object is cloneable and the clone operation fails
378 * @since 3.0
379 */
380 public static <T> T cloneIfPossible(final T o) {
381 final T clone = clone(o);
382 return clone == null ? o : clone;
383 }
384
385 // Null
386 //-----------------------------------------------------------------------
387 /**
388 * <p>Class used as a null placeholder where <code>null</code>
389 * has another meaning.</p>
390 *
391 * <p>For example, in a <code>HashMap</code> the
392 * {@link java.util.HashMap#get(java.lang.Object)} method returns
393 * <code>null</code> if the <code>Map</code> contains
394 * <code>null</code> or if there is no matching key. The
395 * <code>Null</code> placeholder can be used to distinguish between
396 * these two cases.</p>
397 *
398 * <p>Another example is <code>Hashtable</code>, where <code>null</code>
399 * cannot be stored.</p>
400 */
401 public static class Null implements Serializable {
402 /**
403 * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
404 *
405 * @see java.io.Serializable
406 */
407 private static final long serialVersionUID = 7092611880189329093L;
408
409 /**
410 * Restricted constructor - singleton.
411 */
412 Null() {
413 super();
414 }
415
416 /**
417 * <p>Ensure singleton.</p>
418 *
419 * @return the singleton value
420 */
421 private Object readResolve() {
422 return ObjectUtils.NULL;
423 }
424 }
425
426 }