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. However, note that if 086 * the number of arguments does not match the number of occurrences of {@code "%s"} in the format 087 * string, {@code Preconditions} will still behave as expected, and will still include all argument 088 * values in the error message; the message will simply not be formatted exactly as intended. 089 * 090 * <h3>More information</h3> 091 * 092 * <p>See the Guava User Guide on 093 * <a href="http://code.google.com/p/guava-libraries/wiki/PreconditionsExplained">using {@code 094 * Preconditions}</a>. 095 * 096 * @author Kevin Bourrillion 097 * @since 2.0 (imported from Google Collections Library) 098 */ 099@GwtCompatible 100public final class Preconditions { 101 private Preconditions() {} 102 103 /** 104 * Ensures the truth of an expression involving one or more parameters to the calling method. 105 * 106 * @param expression a boolean expression 107 * @throws IllegalArgumentException if {@code expression} is false 108 */ 109 public static void checkArgument(boolean expression) { 110 if (!expression) { 111 throw new IllegalArgumentException(); 112 } 113 } 114 115 /** 116 * Ensures the truth of an expression involving one or more parameters to the calling method. 117 * 118 * @param expression a boolean expression 119 * @param errorMessage the exception message to use if the check fails; will be converted to a 120 * string using {@link String#valueOf(Object)} 121 * @throws IllegalArgumentException if {@code expression} is false 122 */ 123 public static void checkArgument(boolean expression, @Nullable Object errorMessage) { 124 if (!expression) { 125 throw new IllegalArgumentException(String.valueOf(errorMessage)); 126 } 127 } 128 129 /** 130 * Ensures the truth of an expression involving one or more parameters to the calling method. 131 * 132 * @param expression a boolean expression 133 * @param errorMessageTemplate a template for the exception message should the check fail. The 134 * message is formed by replacing each {@code %s} placeholder in the template with an 135 * argument. These are matched by position - the first {@code %s} gets {@code 136 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 137 * in square braces. Unmatched placeholders will be left as-is. 138 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 139 * are converted to strings using {@link String#valueOf(Object)}. 140 * @throws IllegalArgumentException if {@code expression} is false 141 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 142 * {@code errorMessageArgs} is null (don't let this happen) 143 */ 144 public static void checkArgument(boolean expression, 145 @Nullable String errorMessageTemplate, 146 @Nullable Object... errorMessageArgs) { 147 if (!expression) { 148 throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); 149 } 150 } 151 152 /** 153 * Ensures the truth of an expression involving the state of the calling instance, but not 154 * involving any parameters to the calling method. 155 * 156 * @param expression a boolean expression 157 * @throws IllegalStateException if {@code expression} is false 158 */ 159 public static void checkState(boolean expression) { 160 if (!expression) { 161 throw new IllegalStateException(); 162 } 163 } 164 165 /** 166 * Ensures the truth of an expression involving the state of the calling instance, but not 167 * involving any parameters to the calling method. 168 * 169 * @param expression a boolean expression 170 * @param errorMessage the exception message to use if the check fails; will be converted to a 171 * string using {@link String#valueOf(Object)} 172 * @throws IllegalStateException if {@code expression} is false 173 */ 174 public static void checkState(boolean expression, @Nullable Object errorMessage) { 175 if (!expression) { 176 throw new IllegalStateException(String.valueOf(errorMessage)); 177 } 178 } 179 180 /** 181 * Ensures the truth of an expression involving the state of the calling instance, but not 182 * involving any parameters to the calling method. 183 * 184 * @param expression a boolean expression 185 * @param errorMessageTemplate a template for the exception message should the check fail. The 186 * message is formed by replacing each {@code %s} placeholder in the template with an 187 * argument. These are matched by position - the first {@code %s} gets {@code 188 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 189 * in square braces. Unmatched placeholders will be left as-is. 190 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 191 * are converted to strings using {@link String#valueOf(Object)}. 192 * @throws IllegalStateException if {@code expression} is false 193 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 194 * {@code errorMessageArgs} is null (don't let this happen) 195 */ 196 public static void checkState(boolean expression, 197 @Nullable String errorMessageTemplate, 198 @Nullable Object... errorMessageArgs) { 199 if (!expression) { 200 throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); 201 } 202 } 203 204 /** 205 * Ensures that an object reference passed as a parameter to the calling method is not null. 206 * 207 * @param reference an object reference 208 * @return the non-null reference that was validated 209 * @throws NullPointerException if {@code reference} is null 210 */ 211 public static <T> T checkNotNull(T reference) { 212 if (reference == null) { 213 throw new NullPointerException(); 214 } 215 return reference; 216 } 217 218 /** 219 * Ensures that an object reference passed as a parameter to the calling method is not null. 220 * 221 * @param reference an object reference 222 * @param errorMessage the exception message to use if the check fails; will be converted to a 223 * string using {@link String#valueOf(Object)} 224 * @return the non-null reference that was validated 225 * @throws NullPointerException if {@code reference} is null 226 */ 227 public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) { 228 if (reference == null) { 229 throw new NullPointerException(String.valueOf(errorMessage)); 230 } 231 return reference; 232 } 233 234 /** 235 * Ensures that an object reference passed as a parameter to the calling method is not null. 236 * 237 * @param reference an object reference 238 * @param errorMessageTemplate a template for the exception message should the check fail. The 239 * message is formed by replacing each {@code %s} placeholder in the template with an 240 * argument. These are matched by position - the first {@code %s} gets {@code 241 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 242 * in square braces. Unmatched placeholders will be left as-is. 243 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 244 * are converted to strings using {@link String#valueOf(Object)}. 245 * @return the non-null reference that was validated 246 * @throws NullPointerException if {@code reference} is null 247 */ 248 public static <T> T checkNotNull(T reference, 249 @Nullable String errorMessageTemplate, 250 @Nullable Object... errorMessageArgs) { 251 if (reference == null) { 252 // If either of these parameters is null, the right thing happens anyway 253 throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); 254 } 255 return reference; 256 } 257 258 /* 259 * All recent hotspots (as of 2009) *really* like to have the natural code 260 * 261 * if (guardExpression) { 262 * throw new BadException(messageExpression); 263 * } 264 * 265 * refactored so that messageExpression is moved to a separate String-returning method. 266 * 267 * if (guardExpression) { 268 * throw new BadException(badMsg(...)); 269 * } 270 * 271 * The alternative natural refactorings into void or Exception-returning methods are much slower. 272 * This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This 273 * is a hotspot optimizer bug, which should be fixed, but that's a separate, big project). 274 * 275 * The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a 276 * RangeCheckMicroBenchmark in the JDK that was used to test this. 277 * 278 * But the methods in this class want to throw different exceptions, depending on the args, so it 279 * appears that this pattern is not directly applicable. But we can use the ridiculous, devious 280 * trick of throwing an exception in the middle of the construction of another exception. Hotspot 281 * is fine with that. 282 */ 283 284 /** 285 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 286 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 287 * 288 * @param index a user-supplied index identifying an element of an array, list or string 289 * @param size the size of that array, list or string 290 * @return the value of {@code index} 291 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 292 * @throws IllegalArgumentException if {@code size} is negative 293 */ 294 public static int checkElementIndex(int index, int size) { 295 return checkElementIndex(index, size, "index"); 296 } 297 298 /** 299 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 300 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 301 * 302 * @param index a user-supplied index identifying an element of an array, list or string 303 * @param size the size of that array, list or string 304 * @param desc the text to use to describe this index in an error message 305 * @return the value of {@code index} 306 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 307 * @throws IllegalArgumentException if {@code size} is negative 308 */ 309 public static int checkElementIndex( 310 int index, int size, @Nullable String desc) { 311 // Carefully optimized for execution by hotspot (explanatory comment above) 312 if (index < 0 || index >= size) { 313 throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); 314 } 315 return index; 316 } 317 318 private static String badElementIndex(int index, int size, String desc) { 319 if (index < 0) { 320 return format("%s (%s) must not be negative", desc, index); 321 } else if (size < 0) { 322 throw new IllegalArgumentException("negative size: " + size); 323 } else { // index >= size 324 return format("%s (%s) must be less than size (%s)", desc, index, size); 325 } 326 } 327 328 /** 329 * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of 330 * size {@code size}. A position index may range from zero to {@code size}, inclusive. 331 * 332 * @param index a user-supplied index identifying a position in an array, list or string 333 * @param size the size of that array, list or string 334 * @return the value of {@code index} 335 * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} 336 * @throws IllegalArgumentException if {@code size} is negative 337 */ 338 public static int checkPositionIndex(int index, int size) { 339 return checkPositionIndex(index, size, "index"); 340 } 341 342 /** 343 * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of 344 * size {@code size}. A position index may range from zero to {@code size}, inclusive. 345 * 346 * @param index a user-supplied index identifying a position in an array, list or string 347 * @param size the size of that array, list or string 348 * @param desc the text to use to describe this index in an error message 349 * @return the value of {@code index} 350 * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} 351 * @throws IllegalArgumentException if {@code size} is negative 352 */ 353 public static int checkPositionIndex(int index, int size, @Nullable String desc) { 354 // Carefully optimized for execution by hotspot (explanatory comment above) 355 if (index < 0 || index > size) { 356 throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); 357 } 358 return index; 359 } 360 361 private static String badPositionIndex(int index, int size, String desc) { 362 if (index < 0) { 363 return format("%s (%s) must not be negative", desc, index); 364 } else if (size < 0) { 365 throw new IllegalArgumentException("negative size: " + size); 366 } else { // index > size 367 return format("%s (%s) must not be greater than size (%s)", desc, index, size); 368 } 369 } 370 371 /** 372 * Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list 373 * or string of size {@code size}, and are in order. A position index may range from zero to 374 * {@code size}, inclusive. 375 * 376 * @param start a user-supplied index identifying a starting position in an array, list or string 377 * @param end a user-supplied index identifying a ending position in an array, list or string 378 * @param size the size of that array, list or string 379 * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size}, 380 * or if {@code end} is less than {@code start} 381 * @throws IllegalArgumentException if {@code size} is negative 382 */ 383 public static void checkPositionIndexes(int start, int end, int size) { 384 // Carefully optimized for execution by hotspot (explanatory comment above) 385 if (start < 0 || end < start || end > size) { 386 throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); 387 } 388 } 389 390 private static String badPositionIndexes(int start, int end, int size) { 391 if (start < 0 || start > size) { 392 return badPositionIndex(start, size, "start index"); 393 } 394 if (end < 0 || end > size) { 395 return badPositionIndex(end, size, "end index"); 396 } 397 // end < start 398 return format("end index (%s) must not be less than start index (%s)", end, start); 399 } 400 401 /** 402 * Substitutes each {@code %s} in {@code template} with an argument. These are matched by 403 * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than 404 * placeholders, the unmatched arguments will be appended to the end of the formatted message in 405 * square braces. 406 * 407 * @param template a non-null string containing 0 or more {@code %s} placeholders. 408 * @param args the arguments to be substituted into the message template. Arguments are converted 409 * to strings using {@link String#valueOf(Object)}. Arguments can be null. 410 */ 411 // Note that this is somewhat-improperly used from Verify.java as well. 412 static String format(String template, @Nullable Object... args) { 413 template = String.valueOf(template); // null -> "null" 414 415 // start substituting the arguments into the '%s' placeholders 416 StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); 417 int templateStart = 0; 418 int i = 0; 419 while (i < args.length) { 420 int placeholderStart = template.indexOf("%s", templateStart); 421 if (placeholderStart == -1) { 422 break; 423 } 424 builder.append(template.substring(templateStart, placeholderStart)); 425 builder.append(args[i++]); 426 templateStart = placeholderStart + 2; 427 } 428 builder.append(template.substring(templateStart)); 429 430 // if we run out of placeholders, append the extra args in square braces 431 if (i < args.length) { 432 builder.append(" ["); 433 builder.append(args[i++]); 434 while (i < args.length) { 435 builder.append(", "); 436 builder.append(args[i++]); 437 } 438 builder.append(']'); 439 } 440 441 return builder.toString(); 442 } 443}