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 021 /** 022 * <p>Operations on <code>Object</code>.</p> 023 * 024 * <p>This class tries to handle <code>null</code> input gracefully. 025 * An exception will generally not be thrown for a <code>null</code> input. 026 * Each method documents its behaviour in more detail.</p> 027 * 028 * @author Apache Software Foundation 029 * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a> 030 * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a> 031 * @author Daniel L. Rall 032 * @author Gary Gregory 033 * @author Mario Winterer 034 * @author <a href="mailto:david@davidkarlsen.com">David J. M. Karlsen</a> 035 * @since 1.0 036 * @version $Id: ObjectUtils.java 905636 2010-02-02 14:03:32Z niallp $ 037 */ 038 public class ObjectUtils { 039 040 /** 041 * <p>Singleton used as a <code>null</code> placeholder where 042 * <code>null</code> has another meaning.</p> 043 * 044 * <p>For example, in a <code>HashMap</code> the 045 * {@link java.util.HashMap#get(java.lang.Object)} method returns 046 * <code>null</code> if the <code>Map</code> contains 047 * <code>null</code> or if there is no matching key. The 048 * <code>Null</code> placeholder can be used to distinguish between 049 * these two cases.</p> 050 * 051 * <p>Another example is <code>Hashtable</code>, where <code>null</code> 052 * cannot be stored.</p> 053 * 054 * <p>This instance is Serializable.</p> 055 */ 056 public static final Null NULL = new Null(); 057 058 /** 059 * <p><code>ObjectUtils</code> instances should NOT be constructed in 060 * standard programming. Instead, the class should be used as 061 * <code>ObjectUtils.defaultIfNull("a","b");</code>.</p> 062 * 063 * <p>This constructor is public to permit tools that require a JavaBean instance 064 * to operate.</p> 065 */ 066 public ObjectUtils() { 067 super(); 068 } 069 070 // Defaulting 071 //----------------------------------------------------------------------- 072 /** 073 * <p>Returns a default value if the object passed is 074 * <code>null</code>.</p> 075 * 076 * <pre> 077 * ObjectUtils.defaultIfNull(null, null) = null 078 * ObjectUtils.defaultIfNull(null, "") = "" 079 * ObjectUtils.defaultIfNull(null, "zz") = "zz" 080 * ObjectUtils.defaultIfNull("abc", *) = "abc" 081 * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE 082 * </pre> 083 * 084 * @param object the <code>Object</code> to test, may be <code>null</code> 085 * @param defaultValue the default value to return, may be <code>null</code> 086 * @return <code>object</code> if it is not <code>null</code>, defaultValue otherwise 087 */ 088 public static Object defaultIfNull(Object object, Object defaultValue) { 089 return object != null ? object : defaultValue; 090 } 091 092 /** 093 * <p>Compares two objects for equality, where either one or both 094 * objects may be <code>null</code>.</p> 095 * 096 * <pre> 097 * ObjectUtils.equals(null, null) = true 098 * ObjectUtils.equals(null, "") = false 099 * 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 }