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.lang; 018 019 import java.io.Serializable; 020 import java.lang.reflect.Array; 021 import java.lang.reflect.InvocationTargetException; 022 023 import org.apache.commons.lang.exception.CloneFailedException; 024 import org.apache.commons.lang.reflect.MethodUtils; 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 1057434 2011-01-11 01:27:37Z niallp $ 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>Compares two objects for equality, where either one or both 101 * objects may be <code>null</code>.</p> 102 * 103 * <pre> 104 * ObjectUtils.equals(null, null) = true 105 * ObjectUtils.equals(null, "") = false 106 * ObjectUtils.equals("", null) = false 107 * ObjectUtils.equals("", "") = true 108 * ObjectUtils.equals(Boolean.TRUE, null) = false 109 * ObjectUtils.equals(Boolean.TRUE, "true") = false 110 * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true 111 * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false 112 * </pre> 113 * 114 * @param object1 the first object, may be <code>null</code> 115 * @param object2 the second object, may be <code>null</code> 116 * @return <code>true</code> if the values of both objects are the same 117 */ 118 public static boolean equals(Object object1, Object object2) { 119 if (object1 == object2) { 120 return true; 121 } 122 if ((object1 == null) || (object2 == null)) { 123 return false; 124 } 125 return object1.equals(object2); 126 } 127 128 /** 129 * <p>Compares two objects for inequality, where either one or both 130 * objects may be <code>null</code>.</p> 131 * 132 * <pre> 133 * ObjectUtils.notEqual(null, null) = false 134 * ObjectUtils.notEqual(null, "") = true 135 * ObjectUtils.notEqual("", null) = true 136 * ObjectUtils.notEqual("", "") = false 137 * ObjectUtils.notEqual(Boolean.TRUE, null) = true 138 * ObjectUtils.notEqual(Boolean.TRUE, "true") = true 139 * ObjectUtils.notEqual(Boolean.TRUE, Boolean.TRUE) = false 140 * ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true 141 * </pre> 142 * 143 * @param object1 the first object, may be <code>null</code> 144 * @param object2 the second object, may be <code>null</code> 145 * @return <code>false</code> if the values of both objects are the same 146 * @since 2.6 147 */ 148 public static boolean notEqual(Object object1, Object object2) { 149 return ObjectUtils.equals(object1, object2) == false; 150 } 151 152 /** 153 * <p>Gets the hash code of an object returning zero when the 154 * object is <code>null</code>.</p> 155 * 156 * <pre> 157 * ObjectUtils.hashCode(null) = 0 158 * ObjectUtils.hashCode(obj) = obj.hashCode() 159 * </pre> 160 * 161 * @param obj the object to obtain the hash code of, may be <code>null</code> 162 * @return the hash code of the object, or zero if null 163 * @since 2.1 164 */ 165 public static int hashCode(Object obj) { 166 return (obj == null) ? 0 : obj.hashCode(); 167 } 168 169 // Identity ToString 170 //----------------------------------------------------------------------- 171 /** 172 * <p>Gets the toString that would be produced by <code>Object</code> 173 * if a class did not override toString itself. <code>null</code> 174 * will return <code>null</code>.</p> 175 * 176 * <pre> 177 * ObjectUtils.identityToString(null) = null 178 * ObjectUtils.identityToString("") = "java.lang.String@1e23" 179 * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa" 180 * </pre> 181 * 182 * @param object the object to create a toString for, may be 183 * <code>null</code> 184 * @return the default toString text, or <code>null</code> if 185 * <code>null</code> passed in 186 */ 187 public static String identityToString(Object object) { 188 if (object == null) { 189 return null; 190 } 191 StringBuffer buffer = new StringBuffer(); 192 identityToString(buffer, object); 193 return buffer.toString(); 194 } 195 196 /** 197 * <p>Appends the toString that would be produced by <code>Object</code> 198 * if a class did not override toString itself. <code>null</code> 199 * will throw a NullPointerException for either of the two parameters. </p> 200 * 201 * <pre> 202 * ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23" 203 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa" 204 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa") 205 * </pre> 206 * 207 * @param buffer the buffer to append to 208 * @param object the object to create a toString for 209 * @since 2.4 210 */ 211 public static void identityToString(StringBuffer buffer, Object object) { 212 if (object == null) { 213 throw new NullPointerException("Cannot get the toString of a null identity"); 214 } 215 buffer.append(object.getClass().getName()) 216 .append('@') 217 .append(Integer.toHexString(System.identityHashCode(object))); 218 } 219 220 /** 221 * <p>Appends the toString that would be produced by <code>Object</code> 222 * if a class did not override toString itself. <code>null</code> 223 * will return <code>null</code>.</p> 224 * 225 * <pre> 226 * ObjectUtils.appendIdentityToString(*, null) = null 227 * ObjectUtils.appendIdentityToString(null, "") = "java.lang.String@1e23" 228 * ObjectUtils.appendIdentityToString(null, Boolean.TRUE) = "java.lang.Boolean@7fa" 229 * ObjectUtils.appendIdentityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa") 230 * </pre> 231 * 232 * @param buffer the buffer to append to, may be <code>null</code> 233 * @param object the object to create a toString for, may be <code>null</code> 234 * @return the default toString text, or <code>null</code> if 235 * <code>null</code> passed in 236 * @since 2.0 237 * @deprecated The design of this method is bad - see LANG-360. Instead, use identityToString(StringBuffer, Object). 238 */ 239 public static StringBuffer appendIdentityToString(StringBuffer buffer, Object object) { 240 if (object == null) { 241 return null; 242 } 243 if (buffer == null) { 244 buffer = new StringBuffer(); 245 } 246 return buffer 247 .append(object.getClass().getName()) 248 .append('@') 249 .append(Integer.toHexString(System.identityHashCode(object))); 250 } 251 252 // ToString 253 //----------------------------------------------------------------------- 254 /** 255 * <p>Gets the <code>toString</code> of an <code>Object</code> returning 256 * an empty string ("") if <code>null</code> input.</p> 257 * 258 * <pre> 259 * ObjectUtils.toString(null) = "" 260 * ObjectUtils.toString("") = "" 261 * ObjectUtils.toString("bat") = "bat" 262 * ObjectUtils.toString(Boolean.TRUE) = "true" 263 * </pre> 264 * 265 * @see StringUtils#defaultString(String) 266 * @see String#valueOf(Object) 267 * @param obj the Object to <code>toString</code>, 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) { 272 return obj == null ? "" : obj.toString(); 273 } 274 275 /** 276 * <p>Gets the <code>toString</code> of an <code>Object</code> returning 277 * a specified text if <code>null</code> input.</p> 278 * 279 * <pre> 280 * ObjectUtils.toString(null, null) = null 281 * ObjectUtils.toString(null, "null") = "null" 282 * ObjectUtils.toString("", "null") = "" 283 * ObjectUtils.toString("bat", "null") = "bat" 284 * ObjectUtils.toString(Boolean.TRUE, "null") = "true" 285 * </pre> 286 * 287 * @see StringUtils#defaultString(String,String) 288 * @see String#valueOf(Object) 289 * @param obj the Object to <code>toString</code>, may be null 290 * @param nullStr the String to return if <code>null</code> input, may be null 291 * @return the passed in Object's toString, or nullStr if <code>null</code> input 292 * @since 2.0 293 */ 294 public static String toString(Object obj, String nullStr) { 295 return obj == null ? nullStr : obj.toString(); 296 } 297 298 // Min/Max 299 //----------------------------------------------------------------------- 300 /** 301 * Null safe comparison of Comparables. 302 * 303 * @param c1 the first comparable, may be null 304 * @param c2 the second comparable, may be null 305 * @return 306 * <ul> 307 * <li>If both objects are non-null and unequal, the lesser object. 308 * <li>If both objects are non-null and equal, c1. 309 * <li>If one of the comparables is null, the non-null object. 310 * <li>If both the comparables are null, null is returned. 311 * </ul> 312 */ 313 public static Object min(Comparable c1, Comparable c2) { 314 return (compare(c1, c2, true) <= 0 ? c1 : c2); 315 } 316 317 /** 318 * Null safe comparison of Comparables. 319 * 320 * @param c1 the first comparable, may be null 321 * @param c2 the second comparable, may be null 322 * @return 323 * <ul> 324 * <li>If both objects are non-null and unequal, the greater object. 325 * <li>If both objects are non-null and equal, c1. 326 * <li>If one of the comparables is null, the non-null object. 327 * <li>If both the comparables are null, null is returned. 328 * </ul> 329 */ 330 public static Object max(Comparable c1, Comparable c2) { 331 return (compare(c1, c2, false) >= 0 ? c1 : c2); 332 } 333 334 /** 335 * Null safe comparison of Comparables. 336 * {@code null} is assumed to be less than a non-{@code null} value. 337 * 338 * @param c1 the first comparable, may be null 339 * @param c2 the second comparable, may be null 340 * @return a negative value if c1 < c2, zero if c1 = c2 341 * and a positive value if c1 > c2 342 * @since 2.6 343 */ 344 public static int compare(Comparable c1, Comparable c2) { 345 return compare(c1, c2, false); 346 } 347 348 /** 349 * Null safe comparison of Comparables. 350 * 351 * @param c1 the first comparable, may be null 352 * @param c2 the second comparable, may be null 353 * @param nullGreater if true <code>null</code> is considered greater 354 * than a Non-<code>null</code> value or if false <code>null</code> is 355 * considered less than a Non-<code>null</code> value 356 * @return a negative value if c1 < c2, zero if c1 = c2 357 * and a positive value if c1 > c2 358 * @see java.util.Comparator#compare(Object, Object) 359 * @since 2.6 360 */ 361 public static int compare(Comparable c1, Comparable c2, boolean nullGreater) { 362 if (c1 == c2) { 363 return 0; 364 } else if (c1 == null) { 365 return (nullGreater ? 1 : -1); 366 } else if (c2 == null) { 367 return (nullGreater ? -1 : 1); 368 } 369 return c1.compareTo(c2); 370 } 371 372 /** 373 * Clone an object. 374 * 375 * @param o the object to clone 376 * @return the clone if the object implements {@link Cloneable} otherwise <code>null</code> 377 * @throws CloneFailedException if the object is cloneable and the clone operation fails 378 * @since 2.6 379 */ 380 public static Object clone(final Object o) { 381 if (o instanceof Cloneable) { 382 final Object result; 383 if (o.getClass().isArray()) { 384 final Class componentType = o.getClass().getComponentType(); 385 if (!componentType.isPrimitive()) { 386 result = ((Object[])o).clone(); 387 } else { 388 int length = Array.getLength(o); 389 result = Array.newInstance(componentType, length); 390 while (length-- > 0) { 391 Array.set(result, length, Array.get(o, length)); 392 } 393 } 394 } else { 395 try { 396 result = MethodUtils.invokeMethod(o, "clone", null); 397 } catch (final NoSuchMethodException e) { 398 throw new CloneFailedException("Cloneable type " 399 + o.getClass().getName() 400 + " has no clone method", e); 401 } catch (final IllegalAccessException e) { 402 throw new CloneFailedException("Cannot clone Cloneable type " 403 + o.getClass().getName(), e); 404 } catch (final InvocationTargetException e) { 405 throw new CloneFailedException("Exception cloning Cloneable type " 406 + o.getClass().getName(), e.getTargetException()); 407 } 408 } 409 return result; 410 } 411 412 return null; 413 } 414 415 /** 416 * Clone an object if possible. This method is similar to {@link #clone(Object)}, but will 417 * return the provided instance as the return value instead of <code>null</code> if the instance 418 * is not cloneable. This is more convenient if the caller uses different 419 * implementations (e.g. of a service) and some of the implementations do not allow concurrent 420 * processing or have state. In such cases the implementation can simply provide a proper 421 * clone implementation and the caller's code does not have to change. 422 * 423 * @param o the object to clone 424 * @return the clone if the object implements {@link Cloneable} otherwise the object itself 425 * @throws CloneFailedException if the object is cloneable and the clone operation fails 426 * @since 2.6 427 */ 428 public static Object cloneIfPossible(final Object o) { 429 final Object clone = clone(o); 430 return clone == null ? o : clone; 431 } 432 433 // Null 434 //----------------------------------------------------------------------- 435 /** 436 * <p>Class used as a null placeholder where <code>null</code> 437 * has another meaning.</p> 438 * 439 * <p>For example, in a <code>HashMap</code> the 440 * {@link java.util.HashMap#get(java.lang.Object)} method returns 441 * <code>null</code> if the <code>Map</code> contains 442 * <code>null</code> or if there is no matching key. The 443 * <code>Null</code> placeholder can be used to distinguish between 444 * these two cases.</p> 445 * 446 * <p>Another example is <code>Hashtable</code>, where <code>null</code> 447 * cannot be stored.</p> 448 */ 449 public static class Null implements Serializable { 450 /** 451 * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0 452 * 453 * @see java.io.Serializable 454 */ 455 private static final long serialVersionUID = 7092611880189329093L; 456 457 /** 458 * Restricted constructor - singleton. 459 */ 460 Null() { 461 super(); 462 } 463 464 /** 465 * <p>Ensure singleton.</p> 466 * 467 * @return the singleton value 468 */ 469 private Object readResolve() { 470 return ObjectUtils.NULL; 471 } 472 } 473 474 }