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 }