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