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 com.google.common.annotations.GwtCompatible; 018 019import javax.annotation.Nullable; 020 021/** 022 * Static convenience methods that help a method or constructor check whether it was invoked 023 * correctly (whether its <i>preconditions</i> have been met). These methods generally accept a 024 * {@code boolean} expression which is expected to be {@code true} (or in the case of {@code 025 * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or 026 * {@code null}) is passed instead, the {@code Preconditions} method throws an unchecked exception, 027 * which helps the calling method communicate to <i>its</i> caller that <i>that</i> caller has made 028 * a mistake. Example: <pre> {@code 029 * 030 * /** 031 * * Returns the positive square root of the given value. 032 * * 033 * * @throws IllegalArgumentException if the value is negative 034 * *}{@code / 035 * public static double sqrt(double value) { 036 * Preconditions.checkArgument(value >= 0.0, "negative value: %s", value); 037 * // calculate the square root 038 * } 039 * 040 * void exampleBadCaller() { 041 * double d = sqrt(-1.0); 042 * }}</pre> 043 * 044 * In this example, {@code checkArgument} throws an {@code IllegalArgumentException} to indicate 045 * that {@code exampleBadCaller} made an error in <i>its</i> call to {@code sqrt}. 046 * 047 * <h3>Warning about performance</h3> 048 * 049 * <p>The goal of this class is to improve readability of code, but in some circumstances this may 050 * come at a significant performance cost. Remember that parameter values for message construction 051 * must all be computed eagerly, and autoboxing and varargs array creation may happen as well, even 052 * when the precondition check then succeeds (as it should almost always do in production). In some 053 * circumstances these wasted CPU cycles and allocations can add up to a real problem. 054 * Performance-sensitive precondition checks can always be converted to the customary form: 055 * <pre> {@code 056 * 057 * if (value < 0.0) { 058 * throw new IllegalArgumentException("negative value: " + value); 059 * }}</pre> 060 * 061 * <h3>Other types of preconditions</h3> 062 * 063 * <p>Not every type of precondition failure is supported by these methods. Continue to throw 064 * standard JDK exceptions such as {@link java.util.NoSuchElementException} or {@link 065 * UnsupportedOperationException} in the situations they are intended for. 066 * 067 * <h3>Non-preconditions</h3> 068 * 069 * <p>It is of course possible to use the methods of this class to check for invalid conditions 070 * which are <i>not the caller's fault</i>. Doing so is <b>not recommended</b> because it is 071 * misleading to future readers of the code and of stack traces. See 072 * <a href="http://code.google.com/p/guava-libraries/wiki/ConditionalFailuresExplained">Conditional 073 * failures explained</a> in the Guava User Guide for more advice. 074 * 075 * <h3>{@code java.util.Objects.requireNonNull()}</h3> 076 * 077 * <p>Projects which use {@code com.google.common} should generally avoid the use of {@link 078 * java.util.Objects#requireNonNull(Object)}. Instead, use whichever of {@link 079 * #checkNotNull(Object)} or {@link Verify#verifyNotNull(Object)} is appropriate to the situation. 080 * (The same goes for the message-accepting overloads.) 081 * 082 * <h3>Only {@code %s} is supported</h3> 083 * 084 * <p>In {@code Preconditions} error message template strings, only the {@code "%s"} specifier is 085 * supported, not the full range of {@link java.util.Formatter} specifiers. 086 * 087 * <h3>More information</h3> 088 * 089 * <p>See the Guava User Guide on 090 * <a href="http://code.google.com/p/guava-libraries/wiki/PreconditionsExplained">using {@code 091 * Preconditions}</a>. 092 * 093 * @author Kevin Bourrillion 094 * @since 2.0 (imported from Google Collections Library) 095 */ 096@GwtCompatible 097public final class Preconditions { 098 private Preconditions() {} 099 100 /** 101 * Ensures the truth of an expression involving one or more parameters to the calling method. 102 * 103 * @param expression a boolean expression 104 * @throws IllegalArgumentException if {@code expression} is false 105 */ 106 public static void checkArgument(boolean expression) { 107 if (!expression) { 108 throw new IllegalArgumentException(); 109 } 110 } 111 112 /** 113 * Ensures the truth of an expression involving one or more parameters to the calling method. 114 * 115 * @param expression a boolean expression 116 * @param errorMessage the exception message to use if the check fails; will be converted to a 117 * string using {@link String#valueOf(Object)} 118 * @throws IllegalArgumentException if {@code expression} is false 119 */ 120 public static void checkArgument(boolean expression, @Nullable Object errorMessage) { 121 if (!expression) { 122 throw new IllegalArgumentException(String.valueOf(errorMessage)); 123 } 124 } 125 126 /** 127 * Ensures the truth of an expression involving one or more parameters to the calling method. 128 * 129 * @param expression a boolean expression 130 * @param errorMessageTemplate a template for the exception message should the check fail. The 131 * message is formed by replacing each {@code %s} placeholder in the template with an 132 * argument. These are matched by position - the first {@code %s} gets {@code 133 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 134 * in square braces. Unmatched placeholders will be left as-is. 135 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 136 * are converted to strings using {@link String#valueOf(Object)}. 137 * @throws IllegalArgumentException if {@code expression} is false 138 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 139 * {@code errorMessageArgs} is null (don't let this happen) 140 */ 141 public static void checkArgument(boolean expression, 142 @Nullable String errorMessageTemplate, 143 @Nullable Object... errorMessageArgs) { 144 if (!expression) { 145 throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); 146 } 147 } 148 149 /** 150 * Ensures the truth of an expression involving the state of the calling instance, but not 151 * involving any parameters to the calling method. 152 * 153 * @param expression a boolean expression 154 * @throws IllegalStateException if {@code expression} is false 155 */ 156 public static void checkState(boolean expression) { 157 if (!expression) { 158 throw new IllegalStateException(); 159 } 160 } 161 162 /** 163 * Ensures the truth of an expression involving the state of the calling instance, but not 164 * involving any parameters to the calling method. 165 * 166 * @param expression a boolean expression 167 * @param errorMessage the exception message to use if the check fails; will be converted to a 168 * string using {@link String#valueOf(Object)} 169 * @throws IllegalStateException if {@code expression} is false 170 */ 171 public static void checkState(boolean expression, @Nullable Object errorMessage) { 172 if (!expression) { 173 throw new IllegalStateException(String.valueOf(errorMessage)); 174 } 175 } 176 177 /** 178 * Ensures the truth of an expression involving the state of the calling instance, but not 179 * involving any parameters to the calling method. 180 * 181 * @param expression a boolean expression 182 * @param errorMessageTemplate a template for the exception message should the check fail. The 183 * message is formed by replacing each {@code %s} placeholder in the template with an 184 * argument. These are matched by position - the first {@code %s} gets {@code 185 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 186 * in square braces. Unmatched placeholders will be left as-is. 187 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 188 * are converted to strings using {@link String#valueOf(Object)}. 189 * @throws IllegalStateException if {@code expression} is false 190 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 191 * {@code errorMessageArgs} is null (don't let this happen) 192 */ 193 public static void checkState(boolean expression, 194 @Nullable String errorMessageTemplate, 195 @Nullable Object... errorMessageArgs) { 196 if (!expression) { 197 throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); 198 } 199 } 200 201 /** 202 * Ensures that an object reference passed as a parameter to the calling method is not null. 203 * 204 * @param reference an object reference 205 * @return the non-null reference that was validated 206 * @throws NullPointerException if {@code reference} is null 207 */ 208 public static <T> T checkNotNull(T reference) { 209 if (reference == null) { 210 throw new NullPointerException(); 211 } 212 return reference; 213 } 214 215 /** 216 * Ensures that an object reference passed as a parameter to the calling method is not null. 217 * 218 * @param reference an object reference 219 * @param errorMessage the exception message to use if the check fails; will be converted to a 220 * string using {@link String#valueOf(Object)} 221 * @return the non-null reference that was validated 222 * @throws NullPointerException if {@code reference} is null 223 */ 224 public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) { 225 if (reference == null) { 226 throw new NullPointerException(String.valueOf(errorMessage)); 227 } 228 return reference; 229 } 230 231 /** 232 * Ensures that an object reference passed as a parameter to the calling method is not null. 233 * 234 * @param reference an object reference 235 * @param errorMessageTemplate a template for the exception message should the check fail. The 236 * message is formed by replacing each {@code %s} placeholder in the template with an 237 * argument. These are matched by position - the first {@code %s} gets {@code 238 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 239 * in square braces. Unmatched placeholders will be left as-is. 240 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 241 * are converted to strings using {@link String#valueOf(Object)}. 242 * @return the non-null reference that was validated 243 * @throws NullPointerException if {@code reference} is null 244 */ 245 public static <T> T checkNotNull(T reference, 246 @Nullable String errorMessageTemplate, 247 @Nullable Object... errorMessageArgs) { 248 if (reference == null) { 249 // If either of these parameters is null, the right thing happens anyway 250 throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); 251 } 252 return reference; 253 } 254 255 /* 256 * All recent hotspots (as of 2009) *really* like to have the natural code 257 * 258 * if (guardExpression) { 259 * throw new BadException(messageExpression); 260 * } 261 * 262 * refactored so that messageExpression is moved to a separate String-returning method. 263 * 264 * if (guardExpression) { 265 * throw new BadException(badMsg(...)); 266 * } 267 * 268 * The alternative natural refactorings into void or Exception-returning methods are much slower. 269 * This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This 270 * is a hotspot optimizer bug, which should be fixed, but that's a separate, big project). 271 * 272 * The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a 273 * RangeCheckMicroBenchmark in the JDK that was used to test this. 274 * 275 * But the methods in this class want to throw different exceptions, depending on the args, so it 276 * appears that this pattern is not directly applicable. But we can use the ridiculous, devious 277 * trick of throwing an exception in the middle of the construction of another exception. Hotspot 278 * is fine with that. 279 */ 280 281 /** 282 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 283 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 284 * 285 * @param index a user-supplied index identifying an element of an array, list or string 286 * @param size the size of that array, list or string 287 * @return the value of {@code index} 288 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 289 * @throws IllegalArgumentException if {@code size} is negative 290 */ 291 public static int checkElementIndex(int index, int size) { 292 return checkElementIndex(index, size, "index"); 293 } 294 295 /** 296 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 297 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 298 * 299 * @param index a user-supplied index identifying an element of an array, list or string 300 * @param size the size of that array, list or string 301 * @param desc the text to use to describe this index in an error message 302 * @return the value of {@code index} 303 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 304 * @throws IllegalArgumentException if {@code size} is negative 305 */ 306 public static int checkElementIndex( 307 int index, int size, @Nullable String desc) { 308 // Carefully optimized for execution by hotspot (explanatory comment above) 309 if (index < 0 || index >= size) { 310 throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); 311 } 312 return index; 313 } 314 315 private static String badElementIndex(int index, int size, String desc) { 316 if (index < 0) { 317 return format("%s (%s) must not be negative", desc, index); 318 } else if (size < 0) { 319 throw new IllegalArgumentException("negative size: " + size); 320 } else { // index >= size 321 return format("%s (%s) must be less than size (%s)", desc, index, size); 322 } 323 } 324 325 /** 326 * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of 327 * size {@code size}. A position index may range from zero to {@code size}, inclusive. 328 * 329 * @param index a user-supplied index identifying a position in an array, list or string 330 * @param size the size of that array, list or string 331 * @return the value of {@code index} 332 * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} 333 * @throws IllegalArgumentException if {@code size} is negative 334 */ 335 public static int checkPositionIndex(int index, int size) { 336 return checkPositionIndex(index, size, "index"); 337 } 338 339 /** 340 * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of 341 * size {@code size}. A position index may range from zero to {@code size}, inclusive. 342 * 343 * @param index a user-supplied index identifying a position in an array, list or string 344 * @param size the size of that array, list or string 345 * @param desc the text to use to describe this index in an error message 346 * @return the value of {@code index} 347 * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} 348 * @throws IllegalArgumentException if {@code size} is negative 349 */ 350 public static int checkPositionIndex(int index, int size, @Nullable String desc) { 351 // Carefully optimized for execution by hotspot (explanatory comment above) 352 if (index < 0 || index > size) { 353 throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); 354 } 355 return index; 356 } 357 358 private static String badPositionIndex(int index, int size, String desc) { 359 if (index < 0) { 360 return format("%s (%s) must not be negative", desc, index); 361 } else if (size < 0) { 362 throw new IllegalArgumentException("negative size: " + size); 363 } else { // index > size 364 return format("%s (%s) must not be greater than size (%s)", desc, index, size); 365 } 366 } 367 368 /** 369 * Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list 370 * or string of size {@code size}, and are in order. A position index may range from zero to 371 * {@code size}, inclusive. 372 * 373 * @param start a user-supplied index identifying a starting position in an array, list or string 374 * @param end a user-supplied index identifying a ending position in an array, list or string 375 * @param size the size of that array, list or string 376 * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size}, 377 * or if {@code end} is less than {@code start} 378 * @throws IllegalArgumentException if {@code size} is negative 379 */ 380 public static void checkPositionIndexes(int start, int end, int size) { 381 // Carefully optimized for execution by hotspot (explanatory comment above) 382 if (start < 0 || end < start || end > size) { 383 throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); 384 } 385 } 386 387 private static String badPositionIndexes(int start, int end, int size) { 388 if (start < 0 || start > size) { 389 return badPositionIndex(start, size, "start index"); 390 } 391 if (end < 0 || end > size) { 392 return badPositionIndex(end, size, "end index"); 393 } 394 // end < start 395 return format("end index (%s) must not be less than start index (%s)", end, start); 396 } 397 398 /** 399 * Substitutes each {@code %s} in {@code template} with an argument. These are matched by 400 * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than 401 * placeholders, the unmatched arguments will be appended to the end of the formatted message in 402 * square braces. 403 * 404 * @param template a non-null string containing 0 or more {@code %s} placeholders. 405 * @param args the arguments to be substituted into the message template. Arguments are converted 406 * to strings using {@link String#valueOf(Object)}. Arguments can be null. 407 */ 408 // Note that this is somewhat-improperly used from Verify.java as well. 409 static String format(String template, @Nullable Object... args) { 410 template = String.valueOf(template); // null -> "null" 411 412 // start substituting the arguments into the '%s' placeholders 413 StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); 414 int templateStart = 0; 415 int i = 0; 416 while (i < args.length) { 417 int placeholderStart = template.indexOf("%s", templateStart); 418 if (placeholderStart == -1) { 419 break; 420 } 421 builder.append(template.substring(templateStart, placeholderStart)); 422 builder.append(args[i++]); 423 templateStart = placeholderStart + 2; 424 } 425 builder.append(template.substring(templateStart)); 426 427 // if we run out of placeholders, append the extra args in square braces 428 if (i < args.length) { 429 builder.append(" ["); 430 builder.append(args[i++]); 431 while (i < args.length) { 432 builder.append(", "); 433 builder.append(args[i++]); 434 } 435 builder.append(']'); 436 } 437 438 return builder.toString(); 439 } 440}