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 017 package com.google.common.base; 018 019 import static com.google.common.base.Preconditions.checkNotNull; 020 021 import com.google.common.annotations.GwtCompatible; 022 023 import java.util.Arrays; 024 025 import javax.annotation.Nullable; 026 027 /** 028 * Helper functions that can operate on any {@code Object}. 029 * 030 * @author Laurence Gonsalves 031 * @since 2.0 (imported from Google Collections Library) 032 */ 033 @GwtCompatible 034 public final class Objects { 035 private Objects() {} 036 037 /** 038 * Determines whether two possibly-null objects are equal. Returns: 039 * 040 * <ul> 041 * <li>{@code true} if {@code a} and {@code b} are both null. 042 * <li>{@code true} if {@code a} and {@code b} are both non-null and they are 043 * equal according to {@link Object#equals(Object)}. 044 * <li>{@code false} in all other situations. 045 * </ul> 046 * 047 * <p>This assumes that any non-null objects passed to this function conform 048 * to the {@code equals()} contract. 049 */ 050 public static boolean equal(@Nullable Object a, @Nullable Object b) { 051 return a == b || (a != null && a.equals(b)); 052 } 053 054 /** 055 * Generates a hash code for multiple values. The hash code is generated by 056 * calling {@link Arrays#hashCode(Object[])}. 057 * 058 * <p>This is useful for implementing {@link Object#hashCode()}. For example, 059 * in an object that has three properties, {@code x}, {@code y}, and 060 * {@code z}, one could write: 061 * <pre> 062 * public int hashCode() { 063 * return Objects.hashCode(getX(), getY(), getZ()); 064 * }</pre> 065 * 066 * <b>Warning</b>: When a single object is supplied, the returned hash code 067 * does not equal the hash code of that object. 068 */ 069 public static int hashCode(@Nullable Object... objects) { 070 return Arrays.hashCode(objects); 071 } 072 073 /** 074 * Creates an instance of {@link ToStringHelper}. 075 * 076 * <p>This is helpful for implementing {@link Object#toString()}. 077 * Specification by example: <pre> {@code 078 * // Returns "ClassName{}" 079 * Objects.toStringHelper(this) 080 * .toString(); 081 * 082 * // Returns "ClassName{x=1}" 083 * Objects.toStringHelper(this) 084 * .add("x", 1) 085 * .toString(); 086 * 087 * // Returns "MyObject{x=1}" 088 * Objects.toStringHelper("MyObject") 089 * .add("x", 1) 090 * .toString(); 091 * 092 * // Returns "ClassName{x=1, y=foo}" 093 * Objects.toStringHelper(this) 094 * .add("x", 1) 095 * .add("y", "foo") 096 * .toString(); 097 * }}</pre> 098 * 099 * <p>Note that in GWT, class names are often obfuscated. 100 * 101 * @param self the object to generate the string for (typically {@code this}), 102 * used only for its class name 103 * @since 2.0 104 */ 105 public static ToStringHelper toStringHelper(Object self) { 106 return new ToStringHelper(simpleName(self.getClass())); 107 } 108 109 /** 110 * Creates an instance of {@link ToStringHelper} in the same manner as 111 * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz} 112 * instead of using an instance's {@link Object#getClass()}. 113 * 114 * <p>Note that in GWT, class names are often obfuscated. 115 * 116 * @param clazz the {@link Class} of the instance 117 * @since 7.0 (source-compatible since 2.0) 118 */ 119 public static ToStringHelper toStringHelper(Class<?> clazz) { 120 return new ToStringHelper(simpleName(clazz)); 121 } 122 123 /** 124 * Creates an instance of {@link ToStringHelper} in the same manner as 125 * {@link Objects#toStringHelper(Object)}, but using {@code className} instead 126 * of using an instance's {@link Object#getClass()}. 127 * 128 * @param className the name of the instance type 129 * @since 7.0 (source-compatible since 2.0) 130 */ 131 public static ToStringHelper toStringHelper(String className) { 132 return new ToStringHelper(className); 133 } 134 135 /** 136 * {@link Class#getSimpleName()} is not GWT compatible yet, so we 137 * provide our own implementation. 138 */ 139 private static String simpleName(Class<?> clazz) { 140 String name = clazz.getName(); 141 142 // the nth anonymous class has a class name ending in "Outer$n" 143 // and local inner classes have names ending in "Outer.$1Inner" 144 name = name.replaceAll("\\$[0-9]+", "\\$"); 145 146 // we want the name of the inner class all by its lonesome 147 int start = name.lastIndexOf('$'); 148 149 // if this isn't an inner class, just find the start of the 150 // top level class name. 151 if (start == -1) { 152 start = name.lastIndexOf('.'); 153 } 154 return name.substring(start + 1); 155 } 156 157 /** 158 * Returns the first of two given parameters that is not {@code null}, if 159 * either is, or otherwise throws a {@link NullPointerException}. 160 * 161 * <p><b>Note:</b> if {@code first} is represented as an {@code Optional<T>}, 162 * this can be accomplished with {@code first.or(second)}. That approach also 163 * allows for lazy evaluation of the fallback instance, using 164 * {@code first.or(Supplier)}. 165 * 166 * @return {@code first} if {@code first} is not {@code null}, or 167 * {@code second} if {@code first} is {@code null} and {@code second} is 168 * not {@code null} 169 * @throws NullPointerException if both {@code first} and {@code second} were 170 * {@code null} 171 * @since 3.0 172 */ 173 public static <T> T firstNonNull(@Nullable T first, @Nullable T second) { 174 return first != null ? first : checkNotNull(second); 175 } 176 177 /** 178 * Support class for {@link Objects#toStringHelper}. 179 * 180 * @author Jason Lee 181 * @since 2.0 182 */ 183 public static final class ToStringHelper { 184 private final StringBuilder builder; 185 private boolean needsSeparator = false; 186 187 /** 188 * Use {@link Objects#toStringHelper(Object)} to create an instance. 189 */ 190 private ToStringHelper(String className) { 191 checkNotNull(className); 192 this.builder = new StringBuilder(32).append(className).append('{'); 193 } 194 195 /** 196 * Adds a name/value pair to the formatted output in {@code name=value} 197 * format. If {@code value} is {@code null}, the string {@code "null"} 198 * is used. 199 */ 200 public ToStringHelper add(String name, @Nullable Object value) { 201 checkNameAndAppend(name).append(value); 202 return this; 203 } 204 205 /** 206 * Adds a name/value pair to the formatted output in {@code name=value} 207 * format. 208 * 209 * @since 11.0 (source-compatible since 2.0) 210 */ 211 public ToStringHelper add(String name, boolean value) { 212 checkNameAndAppend(name).append(value); 213 return this; 214 } 215 216 /** 217 * Adds a name/value pair to the formatted output in {@code name=value} 218 * format. 219 * 220 * @since 11.0 (source-compatible since 2.0) 221 */ 222 public ToStringHelper add(String name, char value) { 223 checkNameAndAppend(name).append(value); 224 return this; 225 } 226 227 /** 228 * Adds a name/value pair to the formatted output in {@code name=value} 229 * format. 230 * 231 * @since 11.0 (source-compatible since 2.0) 232 */ 233 public ToStringHelper add(String name, double value) { 234 checkNameAndAppend(name).append(value); 235 return this; 236 } 237 238 /** 239 * Adds a name/value pair to the formatted output in {@code name=value} 240 * format. 241 * 242 * @since 11.0 (source-compatible since 2.0) 243 */ 244 public ToStringHelper add(String name, float value) { 245 checkNameAndAppend(name).append(value); 246 return this; 247 } 248 249 /** 250 * Adds a name/value pair to the formatted output in {@code name=value} 251 * format. 252 * 253 * @since 11.0 (source-compatible since 2.0) 254 */ 255 public ToStringHelper add(String name, int value) { 256 checkNameAndAppend(name).append(value); 257 return this; 258 } 259 260 /** 261 * Adds a name/value pair to the formatted output in {@code name=value} 262 * format. 263 * 264 * @since 11.0 (source-compatible since 2.0) 265 */ 266 public ToStringHelper add(String name, long value) { 267 checkNameAndAppend(name).append(value); 268 return this; 269 } 270 271 private StringBuilder checkNameAndAppend(String name) { 272 checkNotNull(name); 273 return maybeAppendSeparator().append(name).append('='); 274 } 275 276 /** 277 * Adds an unnamed value to the formatted output. 278 * 279 * <p>It is strongly encouraged to use {@link #add(String, Object)} instead 280 * and give value a readable name. 281 */ 282 public ToStringHelper addValue(@Nullable Object value) { 283 maybeAppendSeparator().append(value); 284 return this; 285 } 286 287 /** 288 * Adds an unnamed value to the formatted output. 289 * 290 * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead 291 * and give value a readable name. 292 * 293 * @since 11.0 (source-compatible since 2.0) 294 */ 295 public ToStringHelper addValue(boolean value) { 296 maybeAppendSeparator().append(value); 297 return this; 298 } 299 300 /** 301 * Adds an unnamed value to the formatted output. 302 * 303 * <p>It is strongly encouraged to use {@link #add(String, char)} instead 304 * and give value a readable name. 305 * 306 * @since 11.0 (source-compatible since 2.0) 307 */ 308 public ToStringHelper addValue(char value) { 309 maybeAppendSeparator().append(value); 310 return this; 311 } 312 313 /** 314 * Adds an unnamed value to the formatted output. 315 * 316 * <p>It is strongly encouraged to use {@link #add(String, double)} instead 317 * and give value a readable name. 318 * 319 * @since 11.0 (source-compatible since 2.0) 320 */ 321 public ToStringHelper addValue(double value) { 322 maybeAppendSeparator().append(value); 323 return this; 324 } 325 326 /** 327 * Adds an unnamed value to the formatted output. 328 * 329 * <p>It is strongly encouraged to use {@link #add(String, float)} instead 330 * and give value a readable name. 331 * 332 * @since 11.0 (source-compatible since 2.0) 333 */ 334 public ToStringHelper addValue(float value) { 335 maybeAppendSeparator().append(value); 336 return this; 337 } 338 339 /** 340 * Adds an unnamed value to the formatted output. 341 * 342 * <p>It is strongly encouraged to use {@link #add(String, int)} instead 343 * and give value a readable name. 344 * 345 * @since 11.0 (source-compatible since 2.0) 346 */ 347 public ToStringHelper addValue(int value) { 348 maybeAppendSeparator().append(value); 349 return this; 350 } 351 352 /** 353 * Adds an unnamed value to the formatted output. 354 * 355 * <p>It is strongly encouraged to use {@link #add(String, long)} instead 356 * and give value a readable name. 357 * 358 * @since 11.0 (source-compatible since 2.0) 359 */ 360 public ToStringHelper addValue(long value) { 361 maybeAppendSeparator().append(value); 362 return this; 363 } 364 365 /** 366 * Returns a string in the format specified by {@link 367 * Objects#toStringHelper(Object)}. 368 */ 369 @Override public String toString() { 370 try { 371 return builder.append('}').toString(); 372 } finally { 373 // Slice off the closing brace in case there are additional calls to 374 // #add or #addValue. 375 builder.setLength(builder.length() - 1); 376 } 377 } 378 379 private StringBuilder maybeAppendSeparator() { 380 if (needsSeparator) { 381 return builder.append(", "); 382 } else { 383 needsSeparator = true; 384 return builder; 385 } 386 } 387 } 388 }