001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.base; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020 021import com.google.common.annotations.GwtCompatible; 022 023import java.util.Arrays; 024 025import javax.annotation.Nullable; 026 027/** 028 * Helper functions that can operate on any {@code Object}. 029 * 030 * <p>See the Guava User Guide on <a 031 * href="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing 032 * {@code Object} methods with {@code Objects}</a>. 033 * 034 * @author Laurence Gonsalves 035 * @since 2.0 (imported from Google Collections Library) 036 */ 037@GwtCompatible 038public final class Objects { 039 private Objects() {} 040 041 /** 042 * Determines whether two possibly-null objects are equal. Returns: 043 * 044 * <ul> 045 * <li>{@code true} if {@code a} and {@code b} are both null. 046 * <li>{@code true} if {@code a} and {@code b} are both non-null and they are 047 * equal according to {@link Object#equals(Object)}. 048 * <li>{@code false} in all other situations. 049 * </ul> 050 * 051 * <p>This assumes that any non-null objects passed to this function conform 052 * to the {@code equals()} contract. 053 */ 054 public static boolean equal(@Nullable Object a, @Nullable Object b) { 055 return a == b || (a != null && a.equals(b)); 056 } 057 058 /** 059 * Generates a hash code for multiple values. The hash code is generated by 060 * calling {@link Arrays#hashCode(Object[])}. Note that array arguments to 061 * this method, with the exception of a single Object array, do not get any 062 * special handling; their hash codes are based on identity and not contents. 063 * 064 * <p>This is useful for implementing {@link Object#hashCode()}. For example, 065 * in an object that has three properties, {@code x}, {@code y}, and 066 * {@code z}, one could write: 067 * <pre> {@code 068 * public int hashCode() { 069 * return Objects.hashCode(getX(), getY(), getZ()); 070 * }}</pre> 071 * 072 * <p><b>Warning</b>: When a single object is supplied, the returned hash code 073 * does not equal the hash code of that object. 074 */ 075 public static int hashCode(@Nullable Object... objects) { 076 return Arrays.hashCode(objects); 077 } 078 079 /** 080 * Creates an instance of {@link ToStringHelper}. 081 * 082 * <p>This is helpful for implementing {@link Object#toString()}. 083 * Specification by example: <pre> {@code 084 * // Returns "ClassName{}" 085 * Objects.toStringHelper(this) 086 * .toString(); 087 * 088 * // Returns "ClassName{x=1}" 089 * Objects.toStringHelper(this) 090 * .add("x", 1) 091 * .toString(); 092 * 093 * // Returns "MyObject{x=1}" 094 * Objects.toStringHelper("MyObject") 095 * .add("x", 1) 096 * .toString(); 097 * 098 * // Returns "ClassName{x=1, y=foo}" 099 * Objects.toStringHelper(this) 100 * .add("x", 1) 101 * .add("y", "foo") 102 * .toString(); 103 * 104 * // Returns "ClassName{x=1}" 105 * Objects.toStringHelper(this) 106 * .omitNullValues() 107 * .add("x", 1) 108 * .add("y", null) 109 * .toString(); 110 * }}</pre> 111 * 112 * <p>Note that in GWT, class names are often obfuscated. 113 * 114 * @param self the object to generate the string for (typically {@code this}), 115 * used only for its class name 116 * @since 2.0 117 */ 118 public static ToStringHelper toStringHelper(Object self) { 119 return new ToStringHelper(simpleName(self.getClass())); 120 } 121 122 /** 123 * Creates an instance of {@link ToStringHelper} in the same manner as 124 * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz} 125 * instead of using an instance's {@link Object#getClass()}. 126 * 127 * <p>Note that in GWT, class names are often obfuscated. 128 * 129 * @param clazz the {@link Class} of the instance 130 * @since 7.0 (source-compatible since 2.0) 131 */ 132 public static ToStringHelper toStringHelper(Class<?> clazz) { 133 return new ToStringHelper(simpleName(clazz)); 134 } 135 136 /** 137 * Creates an instance of {@link ToStringHelper} in the same manner as 138 * {@link Objects#toStringHelper(Object)}, but using {@code className} instead 139 * of using an instance's {@link Object#getClass()}. 140 * 141 * @param className the name of the instance type 142 * @since 7.0 (source-compatible since 2.0) 143 */ 144 public static ToStringHelper toStringHelper(String className) { 145 return new ToStringHelper(className); 146 } 147 148 /** 149 * {@link Class#getSimpleName()} is not GWT compatible yet, so we 150 * provide our own implementation. 151 */ 152 private static String simpleName(Class<?> clazz) { 153 String name = clazz.getName(); 154 155 // the nth anonymous class has a class name ending in "Outer$n" 156 // and local inner classes have names ending in "Outer.$1Inner" 157 name = name.replaceAll("\\$[0-9]+", "\\$"); 158 159 // we want the name of the inner class all by its lonesome 160 int start = name.lastIndexOf('$'); 161 162 // if this isn't an inner class, just find the start of the 163 // top level class name. 164 if (start == -1) { 165 start = name.lastIndexOf('.'); 166 } 167 return name.substring(start + 1); 168 } 169 170 /** 171 * Returns the first of two given parameters that is not {@code null}, if 172 * either is, or otherwise throws a {@link NullPointerException}. 173 * 174 * <p><b>Note:</b> if {@code first} is represented as an {@code Optional<T>}, 175 * this can be accomplished with {@code first.or(second)}. That approach also 176 * allows for lazy evaluation of the fallback instance, using 177 * {@code first.or(Supplier)}. 178 * 179 * @return {@code first} if {@code first} is not {@code null}, or 180 * {@code second} if {@code first} is {@code null} and {@code second} is 181 * not {@code null} 182 * @throws NullPointerException if both {@code first} and {@code second} were 183 * {@code null} 184 * @since 3.0 185 */ 186 public static <T> T firstNonNull(@Nullable T first, @Nullable T second) { 187 return first != null ? first : checkNotNull(second); 188 } 189 190 /** 191 * Support class for {@link Objects#toStringHelper}. 192 * 193 * @author Jason Lee 194 * @since 2.0 195 */ 196 public static final class ToStringHelper { 197 private final String className; 198 private ValueHolder holderHead = new ValueHolder(); 199 private ValueHolder holderTail = holderHead; 200 private boolean omitNullValues = false; 201 202 /** 203 * Use {@link Objects#toStringHelper(Object)} to create an instance. 204 */ 205 private ToStringHelper(String className) { 206 this.className = checkNotNull(className); 207 } 208 209 /** 210 * Configures the {@link ToStringHelper} so {@link #toString()} will ignore 211 * properties with null value. The order of calling this method, relative 212 * to the {@code add()}/{@code addValue()} methods, is not significant. 213 * 214 * @since 12.0 215 */ 216 public ToStringHelper omitNullValues() { 217 omitNullValues = true; 218 return this; 219 } 220 221 /** 222 * Adds a name/value pair to the formatted output in {@code name=value} 223 * format. If {@code value} is {@code null}, the string {@code "null"} 224 * is used, unless {@link #omitNullValues()} is called, in which case this 225 * name/value pair will not be added. 226 */ 227 public ToStringHelper add(String name, @Nullable Object value) { 228 return addHolder(name, value); 229 } 230 231 /** 232 * Adds a name/value pair to the formatted output in {@code name=value} 233 * format. 234 * 235 * @since 11.0 (source-compatible since 2.0) 236 */ 237 public ToStringHelper add(String name, boolean value) { 238 return addHolder(name, String.valueOf(value)); 239 } 240 241 /** 242 * Adds a name/value pair to the formatted output in {@code name=value} 243 * format. 244 * 245 * @since 11.0 (source-compatible since 2.0) 246 */ 247 public ToStringHelper add(String name, char value) { 248 return addHolder(name, String.valueOf(value)); 249 } 250 251 /** 252 * Adds a name/value pair to the formatted output in {@code name=value} 253 * format. 254 * 255 * @since 11.0 (source-compatible since 2.0) 256 */ 257 public ToStringHelper add(String name, double value) { 258 return addHolder(name, String.valueOf(value)); 259 } 260 261 /** 262 * Adds a name/value pair to the formatted output in {@code name=value} 263 * format. 264 * 265 * @since 11.0 (source-compatible since 2.0) 266 */ 267 public ToStringHelper add(String name, float value) { 268 return addHolder(name, String.valueOf(value)); 269 } 270 271 /** 272 * Adds a name/value pair to the formatted output in {@code name=value} 273 * format. 274 * 275 * @since 11.0 (source-compatible since 2.0) 276 */ 277 public ToStringHelper add(String name, int value) { 278 return addHolder(name, String.valueOf(value)); 279 } 280 281 /** 282 * Adds a name/value pair to the formatted output in {@code name=value} 283 * format. 284 * 285 * @since 11.0 (source-compatible since 2.0) 286 */ 287 public ToStringHelper add(String name, long value) { 288 return addHolder(name, String.valueOf(value)); 289 } 290 291 /** 292 * Adds an unnamed value to the formatted output. 293 * 294 * <p>It is strongly encouraged to use {@link #add(String, Object)} instead 295 * and give value a readable name. 296 */ 297 public ToStringHelper addValue(@Nullable Object value) { 298 return addHolder(value); 299 } 300 301 /** 302 * Adds an unnamed value to the formatted output. 303 * 304 * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead 305 * and give value a readable name. 306 * 307 * @since 11.0 (source-compatible since 2.0) 308 */ 309 public ToStringHelper addValue(boolean value) { 310 return addHolder(String.valueOf(value)); 311 } 312 313 /** 314 * Adds an unnamed value to the formatted output. 315 * 316 * <p>It is strongly encouraged to use {@link #add(String, char)} instead 317 * and give value a readable name. 318 * 319 * @since 11.0 (source-compatible since 2.0) 320 */ 321 public ToStringHelper addValue(char value) { 322 return addHolder(String.valueOf(value)); 323 } 324 325 /** 326 * Adds an unnamed value to the formatted output. 327 * 328 * <p>It is strongly encouraged to use {@link #add(String, double)} instead 329 * and give value a readable name. 330 * 331 * @since 11.0 (source-compatible since 2.0) 332 */ 333 public ToStringHelper addValue(double value) { 334 return addHolder(String.valueOf(value)); 335 } 336 337 /** 338 * Adds an unnamed value to the formatted output. 339 * 340 * <p>It is strongly encouraged to use {@link #add(String, float)} instead 341 * and give value a readable name. 342 * 343 * @since 11.0 (source-compatible since 2.0) 344 */ 345 public ToStringHelper addValue(float value) { 346 return addHolder(String.valueOf(value)); 347 } 348 349 /** 350 * Adds an unnamed value to the formatted output. 351 * 352 * <p>It is strongly encouraged to use {@link #add(String, int)} instead 353 * and give value a readable name. 354 * 355 * @since 11.0 (source-compatible since 2.0) 356 */ 357 public ToStringHelper addValue(int value) { 358 return addHolder(String.valueOf(value)); 359 } 360 361 /** 362 * Adds an unnamed value to the formatted output. 363 * 364 * <p>It is strongly encouraged to use {@link #add(String, long)} instead 365 * and give value a readable name. 366 * 367 * @since 11.0 (source-compatible since 2.0) 368 */ 369 public ToStringHelper addValue(long value) { 370 return addHolder(String.valueOf(value)); 371 } 372 373 /** 374 * Returns a string in the format specified by {@link 375 * Objects#toStringHelper(Object)}. 376 * 377 * <p>After calling this method, you can keep adding more properties to later 378 * call toString() again and get a more complete representation of the 379 * same object; but properties cannot be removed, so this only allows 380 * limited reuse of the helper instance. The helper allows duplication of 381 * properties (multiple name/value pairs with the same name can be added). 382 */ 383 @Override public String toString() { 384 // create a copy to keep it consistent in case value changes 385 boolean omitNullValuesSnapshot = omitNullValues; 386 String nextSeparator = ""; 387 StringBuilder builder = new StringBuilder(32).append(className) 388 .append('{'); 389 for (ValueHolder valueHolder = holderHead.next; valueHolder != null; 390 valueHolder = valueHolder.next) { 391 if (!omitNullValuesSnapshot || valueHolder.value != null) { 392 builder.append(nextSeparator); 393 nextSeparator = ", "; 394 395 if (valueHolder.name != null) { 396 builder.append(valueHolder.name).append('='); 397 } 398 builder.append(valueHolder.value); 399 } 400 } 401 return builder.append('}').toString(); 402 } 403 404 private ValueHolder addHolder() { 405 ValueHolder valueHolder = new ValueHolder(); 406 holderTail = holderTail.next = valueHolder; 407 return valueHolder; 408 } 409 410 private ToStringHelper addHolder(@Nullable Object value) { 411 ValueHolder valueHolder = addHolder(); 412 valueHolder.value = value; 413 return this; 414 } 415 416 private ToStringHelper addHolder(String name, @Nullable Object value) { 417 ValueHolder valueHolder = addHolder(); 418 valueHolder.value = value; 419 valueHolder.name = checkNotNull(name); 420 return this; 421 } 422 423 private static final class ValueHolder { 424 String name; 425 Object value; 426 ValueHolder next; 427 } 428 } 429}