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="https://github.com/google/guava/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="https://github.com/google/guava/wiki/PreconditionsExplained">using {@code 091 * Preconditions}</a>. 092 * 093 * @author Kevin Bourrillion 094 * @since 2.0 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( 142 boolean expression, 143 @Nullable String errorMessageTemplate, 144 @Nullable Object... errorMessageArgs) { 145 if (!expression) { 146 throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); 147 } 148 } 149 150 /** 151 * Ensures the truth of an expression involving the state of the calling instance, but not 152 * involving any parameters to the calling method. 153 * 154 * @param expression a boolean expression 155 * @throws IllegalStateException if {@code expression} is false 156 */ 157 public static void checkState(boolean expression) { 158 if (!expression) { 159 throw new IllegalStateException(); 160 } 161 } 162 163 /** 164 * Ensures the truth of an expression involving the state of the calling instance, but not 165 * involving any parameters to the calling method. 166 * 167 * @param expression a boolean expression 168 * @param errorMessage the exception message to use if the check fails; will be converted to a 169 * string using {@link String#valueOf(Object)} 170 * @throws IllegalStateException if {@code expression} is false 171 */ 172 public static void checkState(boolean expression, @Nullable Object errorMessage) { 173 if (!expression) { 174 throw new IllegalStateException(String.valueOf(errorMessage)); 175 } 176 } 177 178 /** 179 * Ensures the truth of an expression involving the state of the calling instance, but not 180 * involving any parameters to the calling method. 181 * 182 * @param expression a boolean expression 183 * @param errorMessageTemplate a template for the exception message should the check fail. The 184 * message is formed by replacing each {@code %s} placeholder in the template with an 185 * argument. These are matched by position - the first {@code %s} gets {@code 186 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 187 * in square braces. Unmatched placeholders will be left as-is. 188 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 189 * are converted to strings using {@link String#valueOf(Object)}. 190 * @throws IllegalStateException if {@code expression} is false 191 * @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or 192 * {@code errorMessageArgs} is null (don't let this happen) 193 */ 194 public static void checkState( 195 boolean expression, 196 @Nullable String errorMessageTemplate, 197 @Nullable Object... errorMessageArgs) { 198 if (!expression) { 199 throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); 200 } 201 } 202 203 /** 204 * Ensures that an object reference passed as a parameter to the calling method is not null. 205 * 206 * @param reference an object reference 207 * @return the non-null reference that was validated 208 * @throws NullPointerException if {@code reference} is null 209 */ 210 public static <T> T checkNotNull(T reference) { 211 if (reference == null) { 212 throw new NullPointerException(); 213 } 214 return reference; 215 } 216 217 /** 218 * Ensures that an object reference passed as a parameter to the calling method is not null. 219 * 220 * @param reference an object reference 221 * @param errorMessage the exception message to use if the check fails; will be converted to a 222 * string using {@link String#valueOf(Object)} 223 * @return the non-null reference that was validated 224 * @throws NullPointerException if {@code reference} is null 225 */ 226 public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) { 227 if (reference == null) { 228 throw new NullPointerException(String.valueOf(errorMessage)); 229 } 230 return reference; 231 } 232 233 /** 234 * Ensures that an object reference passed as a parameter to the calling method is not null. 235 * 236 * @param reference an object reference 237 * @param errorMessageTemplate a template for the exception message should the check fail. The 238 * message is formed by replacing each {@code %s} placeholder in the template with an 239 * argument. These are matched by position - the first {@code %s} gets {@code 240 * errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message 241 * in square braces. Unmatched placeholders will be left as-is. 242 * @param errorMessageArgs the arguments to be substituted into the message template. Arguments 243 * are converted to strings using {@link String#valueOf(Object)}. 244 * @return the non-null reference that was validated 245 * @throws NullPointerException if {@code reference} is null 246 */ 247 public static <T> T checkNotNull( 248 T reference, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) { 249 if (reference == null) { 250 // If either of these parameters is null, the right thing happens anyway 251 throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); 252 } 253 return reference; 254 } 255 256 /* 257 * All recent hotspots (as of 2009) *really* like to have the natural code 258 * 259 * if (guardExpression) { 260 * throw new BadException(messageExpression); 261 * } 262 * 263 * refactored so that messageExpression is moved to a separate String-returning method. 264 * 265 * if (guardExpression) { 266 * throw new BadException(badMsg(...)); 267 * } 268 * 269 * The alternative natural refactorings into void or Exception-returning methods are much slower. 270 * This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This 271 * is a hotspot optimizer bug, which should be fixed, but that's a separate, big project). 272 * 273 * The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a 274 * RangeCheckMicroBenchmark in the JDK that was used to test this. 275 * 276 * But the methods in this class want to throw different exceptions, depending on the args, so it 277 * appears that this pattern is not directly applicable. But we can use the ridiculous, devious 278 * trick of throwing an exception in the middle of the construction of another exception. Hotspot 279 * is fine with that. 280 */ 281 282 /** 283 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 284 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 285 * 286 * @param index a user-supplied index identifying an element of an array, list or string 287 * @param size the size of that array, list or string 288 * @return the value of {@code index} 289 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 290 * @throws IllegalArgumentException if {@code size} is negative 291 */ 292 public static int checkElementIndex(int index, int size) { 293 return checkElementIndex(index, size, "index"); 294 } 295 296 /** 297 * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size 298 * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. 299 * 300 * @param index a user-supplied index identifying an element of an array, list or string 301 * @param size the size of that array, list or string 302 * @param desc the text to use to describe this index in an error message 303 * @return the value of {@code index} 304 * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} 305 * @throws IllegalArgumentException if {@code size} is negative 306 */ 307 public static int checkElementIndex(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}