View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang;
18  
19  import java.io.Serializable;
20  
21  /**
22   * <p>Operations on <code>Object</code>.</p>
23   * 
24   * <p>This class tries to handle <code>null</code> input gracefully.
25   * An exception will generally not be thrown for a <code>null</code> input.
26   * Each method documents its behaviour in more detail.</p>
27   *
28   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
29   * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
30   * @author Daniel L. Rall
31   * @author Stephen Colebourne
32   * @author Gary Gregory
33   * @author Mario Winterer
34   * @author <a href="mailto:david@davidkarlsen.com">David J. M. Karlsen</a>
35   * @since 1.0
36   * @version $Id: ObjectUtils.java 594336 2007-11-12 22:54:02Z bayard $
37   */
38  public class ObjectUtils {
39  
40      /**
41       * <p>Singleton used as a <code>null</code> placeholder where
42       * <code>null</code> has another meaning.</p>
43       *
44       * <p>For example, in a <code>HashMap</code> the
45       * {@link java.util.HashMap#get(java.lang.Object)} method returns
46       * <code>null</code> if the <code>Map</code> contains
47       * <code>null</code> or if there is no matching key. The
48       * <code>Null</code> placeholder can be used to distinguish between
49       * these two cases.</p>
50       *
51       * <p>Another example is <code>Hashtable</code>, where <code>null</code>
52       * cannot be stored.</p>
53       *
54       * <p>This instance is Serializable.</p>
55       */
56      public static final Null NULL = new Null();
57      
58      /**
59       * <p><code>ObjectUtils</code> instances should NOT be constructed in
60       * standard programming. Instead, the class should be used as
61       * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p>
62       *
63       * <p>This constructor is public to permit tools that require a JavaBean instance
64       * to operate.</p>
65       */
66      public ObjectUtils() {
67          super();
68      }
69  
70      // Defaulting
71      //-----------------------------------------------------------------------
72      /**
73       * <p>Returns a default value if the object passed is
74       * <code>null</code>.</p>
75       * 
76       * <pre>
77       * ObjectUtils.defaultIfNull(null, null)      = null
78       * ObjectUtils.defaultIfNull(null, "")        = ""
79       * ObjectUtils.defaultIfNull(null, "zz")      = "zz"
80       * ObjectUtils.defaultIfNull("abc", *)        = "abc"
81       * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
82       * </pre>
83       *
84       * @param object  the <code>Object</code> to test, may be <code>null</code>
85       * @param defaultValue  the default value to return, may be <code>null</code>
86       * @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise
87       */
88      public static Object defaultIfNull(Object object, Object defaultValue) {
89          return object != null ? object : defaultValue;
90      }
91  
92      /**
93       * <p>Compares two objects for equality, where either one or both
94       * objects may be <code>null</code>.</p>
95       *
96       * <pre>
97       * ObjectUtils.equals(null, null)                  = true
98       * ObjectUtils.equals(null, "")                    = false
99       * ObjectUtils.equals("", null)                    = false
100      * ObjectUtils.equals("", "")                      = true
101      * ObjectUtils.equals(Boolean.TRUE, null)          = false
102      * ObjectUtils.equals(Boolean.TRUE, "true")        = false
103      * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE)  = true
104      * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
105      * </pre>
106      *
107      * @param object1  the first object, may be <code>null</code>
108      * @param object2  the second object, may be <code>null</code>
109      * @return <code>true</code> if the values of both objects are the same
110      */
111     public static boolean equals(Object object1, Object object2) {
112         if (object1 == object2) {
113             return true;
114         }
115         if ((object1 == null) || (object2 == null)) {
116             return false;
117         }
118         return object1.equals(object2);
119     }
120 
121     /**
122      * <p>Gets the hash code of an object returning zero when the
123      * object is <code>null</code>.</p>
124      *
125      * <pre>
126      * ObjectUtils.hashCode(null)   = 0
127      * ObjectUtils.hashCode(obj)    = obj.hashCode()
128      * </pre>
129      *
130      * @param obj  the object to obtain the hash code of, may be <code>null</code>
131      * @return the hash code of the object, or zero if null
132      * @since 2.1
133      */
134     public static int hashCode(Object obj) {
135         return (obj == null) ? 0 : obj.hashCode();
136     }
137 
138     // Identity ToString
139     //-----------------------------------------------------------------------
140     /**
141      * <p>Gets the toString that would be produced by <code>Object</code>
142      * if a class did not override toString itself. <code>null</code>
143      * will return <code>null</code>.</p>
144      *
145      * <pre>
146      * ObjectUtils.identityToString(null)         = null
147      * ObjectUtils.identityToString("")           = "java.lang.String@1e23"
148      * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
149      * </pre>
150      *
151      * @param object  the object to create a toString for, may be
152      *  <code>null</code>
153      * @return the default toString text, or <code>null</code> if
154      *  <code>null</code> passed in
155      */
156     public static String identityToString(Object object) {
157         if (object == null) {
158             return null;
159         }
160         StringBuffer buffer = new StringBuffer();
161         identityToString(buffer, object);
162         return buffer.toString();
163     }
164 
165     /**
166      * <p>Appends the toString that would be produced by <code>Object</code>
167      * if a class did not override toString itself. <code>null</code>
168      * will throw a NullPointerException for either of the two parameters. </p>
169      *
170      * <pre>
171      * ObjectUtils.identityToString(buf, "")            = buf.append("java.lang.String@1e23"
172      * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa"
173      * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
174      * </pre>
175      *
176      * @param buffer  the buffer to append to
177      * @param object  the object to create a toString for
178      * @since 2.4
179      */
180     public static void identityToString(StringBuffer buffer, Object object) {
181         if (object == null) {
182             throw new NullPointerException("Cannot get the toString of a null identity");
183         }
184         buffer.append(object.getClass().getName())
185               .append('@')
186               .append(Integer.toHexString(System.identityHashCode(object)));
187     }
188 
189     /**
190      * <p>Appends the toString that would be produced by <code>Object</code>
191      * if a class did not override toString itself. <code>null</code>
192      * will return <code>null</code>.</p>
193      *
194      * <pre>
195      * ObjectUtils.appendIdentityToString(*, null)            = null
196      * ObjectUtils.appendIdentityToString(null, "")           = "java.lang.String@1e23"
197      * ObjectUtils.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa"
198      * ObjectUtils.appendIdentityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
199      * </pre>
200      *
201      * @param buffer  the buffer to append to, may be <code>null</code>
202      * @param object  the object to create a toString for, may be <code>null</code>
203      * @return the default toString text, or <code>null</code> if
204      *  <code>null</code> passed in
205      * @since 2.0
206      * @deprecated The design of this method is bad - see LANG-360. Instead, use identityToString(StringBuffer, Object).
207      */
208     public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) {
209         if (object == null) {
210             return null;
211         }
212         if (buffer == null) {
213             buffer = new StringBuffer();
214         }
215         return buffer
216             .append(object.getClass().getName())
217             .append('@')
218             .append(Integer.toHexString(System.identityHashCode(object)));
219     }
220 
221     // ToString
222     //-----------------------------------------------------------------------
223     /**
224      * <p>Gets the <code>toString</code> of an <code>Object</code> returning
225      * an empty string ("") if <code>null</code> input.</p>
226      * 
227      * <pre>
228      * ObjectUtils.toString(null)         = ""
229      * ObjectUtils.toString("")           = ""
230      * ObjectUtils.toString("bat")        = "bat"
231      * ObjectUtils.toString(Boolean.TRUE) = "true"
232      * </pre>
233      * 
234      * @see StringUtils#defaultString(String)
235      * @see String#valueOf(Object)
236      * @param obj  the Object to <code>toString</code>, may be null
237      * @return the passed in Object's toString, or nullStr if <code>null</code> input
238      * @since 2.0
239      */
240     public static String toString(Object obj) {
241         return obj == null ? "" : obj.toString();
242     }
243 
244     /**
245      * <p>Gets the <code>toString</code> of an <code>Object</code> returning
246      * a specified text if <code>null</code> input.</p>
247      * 
248      * <pre>
249      * ObjectUtils.toString(null, null)           = null
250      * ObjectUtils.toString(null, "null")         = "null"
251      * ObjectUtils.toString("", "null")           = ""
252      * ObjectUtils.toString("bat", "null")        = "bat"
253      * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
254      * </pre>
255      * 
256      * @see StringUtils#defaultString(String,String)
257      * @see String#valueOf(Object)
258      * @param obj  the Object to <code>toString</code>, may be null
259      * @param nullStr  the String to return if <code>null</code> input, may be null
260      * @return the passed in Object's toString, or nullStr if <code>null</code> input
261      * @since 2.0
262      */
263     public static String toString(Object obj, String nullStr) {
264         return obj == null ? nullStr : obj.toString();
265     }
266 
267     // Min/Max
268     //-----------------------------------------------------------------------
269     /**
270      * Null safe comparison of Comparables.
271      * 
272      * @param c1  the first comparable, may be null
273      * @param c2  the second comparable, may be null
274      * @return
275      *  <ul>
276      *   <li>If both objects are non-null and unequal, the lesser object.
277      *   <li>If both objects are non-null and equal, c1.
278      *   <li>If one of the comparables is null, the non-null object.
279      *   <li>If both the comparables are null, null is returned.
280      *  </ul>
281      */
282     public static Object min(Comparable c1, Comparable c2) {
283         if (c1 != null && c2 != null) {
284             return c1.compareTo(c2) < 1 ? c1 : c2;
285         } else {
286             return c1 != null ? c1 : c2;
287         }                              
288     }
289 
290     /**
291      * Null safe comparison of Comparables.
292      * 
293      * @param c1  the first comparable, may be null
294      * @param c2  the second comparable, may be null
295      * @return
296      *  <ul>
297      *   <li>If both objects are non-null and unequal, the greater object.
298      *   <li>If both objects are non-null and equal, c1.
299      *   <li>If one of the comparables is null, the non-null object.
300      *   <li>If both the comparables are null, null is returned.
301      *  </ul>
302      */
303     public static Object max(Comparable c1, Comparable c2) {
304         if (c1 != null && c2 != null) {
305             return c1.compareTo(c2) >= 0 ? c1 : c2;
306         } else {
307             return c1 != null ? c1 : c2;
308         }
309     }
310 
311     // Null
312     //-----------------------------------------------------------------------
313     /**
314      * <p>Class used as a null placeholder where <code>null</code>
315      * has another meaning.</p>
316      *
317      * <p>For example, in a <code>HashMap</code> the
318      * {@link java.util.HashMap#get(java.lang.Object)} method returns
319      * <code>null</code> if the <code>Map</code> contains
320      * <code>null</code> or if there is no matching key. The
321      * <code>Null</code> placeholder can be used to distinguish between
322      * these two cases.</p>
323      *
324      * <p>Another example is <code>Hashtable</code>, where <code>null</code>
325      * cannot be stored.</p>
326      */
327     public static class Null implements Serializable {
328         /**
329          * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
330          * 
331          * @see java.io.Serializable
332          */
333         private static final long serialVersionUID = 7092611880189329093L;
334         
335         /**
336          * Restricted constructor - singleton.
337          */
338         Null() {
339             super();
340         }
341         
342         /**
343          * <p>Ensure singleton.</p>
344          * 
345          * @return the singleton value
346          */
347         private Object readResolve() {
348             return ObjectUtils.NULL;
349         }
350     }
351 
352 }