001 /* 002 * Copyright (C) 2007 Google Inc. 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 com.google.common.annotations.GwtCompatible; 020 import com.google.common.annotations.VisibleForTesting; 021 022 import java.util.ArrayList; 023 import java.util.Arrays; 024 import java.util.List; 025 026 import javax.annotation.Nullable; 027 028 /** 029 * Helper functions that can operate on any {@code Object}. 030 * 031 * @author Laurence Gonsalves 032 * @since 2 (imported from Google Collections Library) 033 */ 034 @GwtCompatible 035 public final class Objects { 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 044 * equal according to {@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 049 * to the {@code equals()} contract. 050 */ 051 public static boolean equal(@Nullable Object a, @Nullable Object b) { 052 return a == b || (a != null && a.equals(b)); 053 } 054 055 /** 056 * Generates a hash code for multiple values. The hash code is generated by 057 * calling {@link Arrays#hashCode(Object[])}. 058 * 059 * <p>This is useful for implementing {@link Object#hashCode()}. For example, 060 * in an object that has three properties, {@code x}, {@code y}, and 061 * {@code z}, one could write: 062 * <pre> 063 * public int hashCode() { 064 * return Objects.hashCode(getX(), getY(), getZ()); 065 * }</pre> 066 * 067 * <b>Warning</b>: When a single object is supplied, the returned hash code 068 * does not equal the hash code of that object. 069 */ 070 public static int hashCode(Object... objects) { 071 return Arrays.hashCode(objects); 072 } 073 074 /** 075 * Creates an instance of {@link ToStringHelper}. 076 * 077 * <p>This is helpful for implementing {@link Object#toString()}. For 078 * example, in an object that contains two member variables, {@code x}, 079 * and {@code y}, one could write:<pre> <tt> 080 * public class ClassName { 081 * public String toString() { 082 * return Objects.toStringHelper(this) 083 * .add("x", x) 084 * .add("y", y) 085 * .toString(); 086 * } 087 * }</tt> 088 * </pre> 089 * 090 * Assuming the values of {@code x} and {@code y} are 1 and 2, 091 * this code snippet returns the string <tt>"ClassName{x=1, y=2}"</tt>. 092 * 093 * @param self the object to generate the string for (typically {@code this}), 094 * used only for its class name 095 * @since 2 096 */ 097 public static ToStringHelper toStringHelper(Object self) { 098 return new ToStringHelper(self); 099 } 100 101 /** 102 * Returns the first of two given parameters that is not {@code null}, if 103 * either is, or otherwise throws a {@link NullPointerException}. 104 * 105 * @return {@code first} if {@code first} is not {@code null}, or 106 * {@code second} if {@code first} is {@code null} and {@code second} is 107 * not {@code null} 108 * @throws NullPointerException if both {@code first} and {@code second} were 109 * {@code null} 110 * @since 3 111 */ 112 public static <T> T firstNonNull(@Nullable T first, @Nullable T second) { 113 return first != null ? first : Preconditions.checkNotNull(second); 114 } 115 116 /** 117 * Support class for {@link Objects#toStringHelper}. 118 * 119 * @author Jason Lee 120 * @since 2 121 */ 122 public static class ToStringHelper { 123 private final List<String> fieldString = new ArrayList<String>(); 124 private final Object instance; 125 126 /** 127 * Use {@link Objects#toStringHelper(Object)} to create an instance. 128 */ 129 private ToStringHelper(Object instance) { 130 this.instance = Preconditions.checkNotNull(instance); 131 } 132 133 /** 134 * Adds a name/value pair to the formatted output in {@code name=value} 135 * format. If {@code value} is {@code null}, the string {@code "null"} 136 * is used. 137 */ 138 public ToStringHelper add(String name, @Nullable Object value) { 139 return addValue(Preconditions.checkNotNull(name) + "=" + value); 140 } 141 142 /** 143 * Adds a value to the formatted output in {@code value} format.<p/> 144 * 145 * It is strongly encouraged to use {@link #add(String, Object)} instead and 146 * give value a readable name. 147 */ 148 public ToStringHelper addValue(@Nullable Object value) { 149 fieldString.add(String.valueOf(value)); 150 return this; 151 } 152 153 private static final Joiner JOINER = Joiner.on(", "); 154 155 /** 156 * Returns the formatted string. 157 */ 158 @Override public String toString() { 159 StringBuilder builder = new StringBuilder(100) 160 .append(simpleName(instance.getClass())) 161 .append('{'); 162 return JOINER.appendTo(builder, fieldString) 163 .append('}') 164 .toString(); 165 } 166 167 /** 168 * {@link Class#getSimpleName()} is not GWT compatible yet, so we 169 * provide our own implementation. 170 */ 171 @VisibleForTesting 172 static String simpleName(Class<?> clazz) { 173 String name = clazz.getName(); 174 175 // we want the name of the inner class all by its lonesome 176 int start = name.lastIndexOf('$'); 177 178 // if this isn't an inner class, just find the start of the 179 // top level class name. 180 if (start == -1) { 181 start = name.lastIndexOf('.'); 182 } 183 return name.substring(start + 1); 184 } 185 } 186 }