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 {@link Optional}, 175 * this can be accomplished with 176 * {@linkplain Optional#or(Object) first.or(second)}. 177 * That approach also allows for lazy evaluation of the fallback instance, 178 * using {@linkplain Optional#or(Supplier) first.or(Supplier)}. 179 * 180 * @return {@code first} if {@code first} is not {@code null}, or 181 * {@code second} if {@code first} is {@code null} and {@code second} is 182 * not {@code null} 183 * @throws NullPointerException if both {@code first} and {@code second} were 184 * {@code null} 185 * @since 3.0 186 */ 187 public static <T> T firstNonNull(@Nullable T first, @Nullable T second) { 188 return first != null ? first : checkNotNull(second); 189 } 190 191 /** 192 * Support class for {@link Objects#toStringHelper}. 193 * 194 * @author Jason Lee 195 * @since 2.0 196 */ 197 public static final class ToStringHelper { 198 private final String className; 199 private ValueHolder holderHead = new ValueHolder(); 200 private ValueHolder holderTail = holderHead; 201 private boolean omitNullValues = false; 202 203 /** 204 * Use {@link Objects#toStringHelper(Object)} to create an instance. 205 */ 206 private ToStringHelper(String className) { 207 this.className = checkNotNull(className); 208 } 209 210 /** 211 * Configures the {@link ToStringHelper} so {@link #toString()} will ignore 212 * properties with null value. The order of calling this method, relative 213 * to the {@code add()}/{@code addValue()} methods, is not significant. 214 * 215 * @since 12.0 216 */ 217 public ToStringHelper omitNullValues() { 218 omitNullValues = true; 219 return this; 220 } 221 222 /** 223 * Adds a name/value pair to the formatted output in {@code name=value} 224 * format. If {@code value} is {@code null}, the string {@code "null"} 225 * is used, unless {@link #omitNullValues()} is called, in which case this 226 * name/value pair will not be added. 227 */ 228 public ToStringHelper add(String name, @Nullable Object value) { 229 return addHolder(name, value); 230 } 231 232 /** 233 * Adds a name/value pair to the formatted output in {@code name=value} 234 * format. 235 * 236 * @since 11.0 (source-compatible since 2.0) 237 */ 238 public ToStringHelper add(String name, boolean value) { 239 return addHolder(name, String.valueOf(value)); 240 } 241 242 /** 243 * Adds a name/value pair to the formatted output in {@code name=value} 244 * format. 245 * 246 * @since 11.0 (source-compatible since 2.0) 247 */ 248 public ToStringHelper add(String name, char value) { 249 return addHolder(name, String.valueOf(value)); 250 } 251 252 /** 253 * Adds a name/value pair to the formatted output in {@code name=value} 254 * format. 255 * 256 * @since 11.0 (source-compatible since 2.0) 257 */ 258 public ToStringHelper add(String name, double value) { 259 return addHolder(name, String.valueOf(value)); 260 } 261 262 /** 263 * Adds a name/value pair to the formatted output in {@code name=value} 264 * format. 265 * 266 * @since 11.0 (source-compatible since 2.0) 267 */ 268 public ToStringHelper add(String name, float value) { 269 return addHolder(name, String.valueOf(value)); 270 } 271 272 /** 273 * Adds a name/value pair to the formatted output in {@code name=value} 274 * format. 275 * 276 * @since 11.0 (source-compatible since 2.0) 277 */ 278 public ToStringHelper add(String name, int value) { 279 return addHolder(name, String.valueOf(value)); 280 } 281 282 /** 283 * Adds a name/value pair to the formatted output in {@code name=value} 284 * format. 285 * 286 * @since 11.0 (source-compatible since 2.0) 287 */ 288 public ToStringHelper add(String name, long value) { 289 return addHolder(name, String.valueOf(value)); 290 } 291 292 /** 293 * Adds an unnamed value to the formatted output. 294 * 295 * <p>It is strongly encouraged to use {@link #add(String, Object)} instead 296 * and give value a readable name. 297 */ 298 public ToStringHelper addValue(@Nullable Object value) { 299 return addHolder(value); 300 } 301 302 /** 303 * Adds an unnamed value to the formatted output. 304 * 305 * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead 306 * and give value a readable name. 307 * 308 * @since 11.0 (source-compatible since 2.0) 309 */ 310 public ToStringHelper addValue(boolean value) { 311 return addHolder(String.valueOf(value)); 312 } 313 314 /** 315 * Adds an unnamed value to the formatted output. 316 * 317 * <p>It is strongly encouraged to use {@link #add(String, char)} instead 318 * and give value a readable name. 319 * 320 * @since 11.0 (source-compatible since 2.0) 321 */ 322 public ToStringHelper addValue(char value) { 323 return addHolder(String.valueOf(value)); 324 } 325 326 /** 327 * Adds an unnamed value to the formatted output. 328 * 329 * <p>It is strongly encouraged to use {@link #add(String, double)} instead 330 * and give value a readable name. 331 * 332 * @since 11.0 (source-compatible since 2.0) 333 */ 334 public ToStringHelper addValue(double value) { 335 return addHolder(String.valueOf(value)); 336 } 337 338 /** 339 * Adds an unnamed value to the formatted output. 340 * 341 * <p>It is strongly encouraged to use {@link #add(String, float)} instead 342 * and give value a readable name. 343 * 344 * @since 11.0 (source-compatible since 2.0) 345 */ 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 354 * and give value a readable name. 355 * 356 * @since 11.0 (source-compatible since 2.0) 357 */ 358 public ToStringHelper addValue(int value) { 359 return addHolder(String.valueOf(value)); 360 } 361 362 /** 363 * Adds an unnamed value to the formatted output. 364 * 365 * <p>It is strongly encouraged to use {@link #add(String, long)} instead 366 * and give value a readable name. 367 * 368 * @since 11.0 (source-compatible since 2.0) 369 */ 370 public ToStringHelper addValue(long value) { 371 return addHolder(String.valueOf(value)); 372 } 373 374 /** 375 * Returns a string in the format specified by {@link 376 * Objects#toStringHelper(Object)}. 377 * 378 * <p>After calling this method, you can keep adding more properties to later 379 * call toString() again and get a more complete representation of the 380 * same object; but properties cannot be removed, so this only allows 381 * limited reuse of the helper instance. The helper allows duplication of 382 * properties (multiple name/value pairs with the same name can be added). 383 */ 384 @Override public String toString() { 385 // create a copy to keep it consistent in case value changes 386 boolean omitNullValuesSnapshot = omitNullValues; 387 String nextSeparator = ""; 388 StringBuilder builder = new StringBuilder(32).append(className) 389 .append('{'); 390 for (ValueHolder valueHolder = holderHead.next; valueHolder != null; 391 valueHolder = valueHolder.next) { 392 if (!omitNullValuesSnapshot || valueHolder.value != null) { 393 builder.append(nextSeparator); 394 nextSeparator = ", "; 395 396 if (valueHolder.name != null) { 397 builder.append(valueHolder.name).append('='); 398 } 399 builder.append(valueHolder.value); 400 } 401 } 402 return builder.append('}').toString(); 403 } 404 405 private ValueHolder addHolder() { 406 ValueHolder valueHolder = new ValueHolder(); 407 holderTail = holderTail.next = valueHolder; 408 return valueHolder; 409 } 410 411 private ToStringHelper addHolder(@Nullable Object value) { 412 ValueHolder valueHolder = addHolder(); 413 valueHolder.value = value; 414 return this; 415 } 416 417 private ToStringHelper addHolder(String name, @Nullable Object value) { 418 ValueHolder valueHolder = addHolder(); 419 valueHolder.value = value; 420 valueHolder.name = checkNotNull(name); 421 return this; 422 } 423 424 private static final class ValueHolder { 425 String name; 426 Object value; 427 ValueHolder next; 428 } 429 } 430}