1 package org.djutils.exceptions; 2 3 import java.lang.reflect.Constructor; 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.IllegalFormatException; 7 import java.util.List; 8 import java.util.function.Supplier; 9 10 import org.djutils.reflection.ClassUtil; 11 12 /** 13 * The Throw class has a number of static methods that make it easy to throw an exception under conditions for any Exception 14 * class, including the standard Java exceptions and exceptions from libraries that are used in the project. Instead of: 15 * 16 * <pre> 17 * if (car == null) 18 * { 19 * throw new NullPointerException("Car may not be null."); 20 * } 21 * if (Double.isNaN(car.getPosition())) 22 * { 23 * throw new IllegalArgumentException("Position of car " + car + " is NaN."); 24 * } 25 * </pre> 26 * 27 * we can write: 28 * 29 * <pre> 30 * Throw.whenNull(car, "Car may not be null."); 31 * Throw.when(Double.isNaN(car.getPosition()), IllegalArgumentException.class, "Position of car %s is NaN.", car); 32 * </pre> 33 * 34 * The exception message can be formatted with additional arguments, such that the overhead of building the exception message 35 * only occurs if the exception condition is met. All methods have a version where the first parameter is returned. Thereby, the 36 * Throw can be used as part of a <b>super</b>(...) call in a constructor. 37 * <p> 38 * Copyright (c) 2016-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See 39 * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is 40 * distributed under a three-clause BSD-style license, which can be found at 41 * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>. 42 * </p> 43 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a> 44 * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a> 45 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 46 */ 47 @SuppressWarnings("checkstyle:linelength") 48 public final class Throw 49 { 50 /** private constructor for utility class. */ 51 private Throw() 52 { 53 // utility class 54 } 55 56 /** 57 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 58 * follows: <br> 59 * 60 * <pre> 61 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, "Value may not be NaN."); 62 * </pre> 63 * 64 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 65 * @param throwableClass the Throwable type to throw 66 * @param message the message to use in the exception 67 * @throws T the throwable to throw on true condition 68 * @param <T> the Throwable type 69 */ 70 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, final String message) 71 throws T 72 { 73 if (condition) 74 { 75 throwMessage(throwableClass, message, null); 76 } 77 } 78 79 /** 80 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 81 * follows: <br> 82 * 83 * <pre> 84 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, () -> object.reportStatus()); 85 * </pre> 86 * 87 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 88 * @param throwableClass the Throwable type to throw 89 * @param stringSupplier the supplier that provides the message to use in the exception 90 * @throws T the throwable to throw on true condition 91 * @param <T> the Throwable type 92 */ 93 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, 94 final Supplier<String> stringSupplier) throws T 95 { 96 if (condition) 97 { 98 throwMessage(throwableClass, stringSupplier.get(), null); 99 } 100 } 101 102 /** 103 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 104 * follows: <br> 105 * 106 * <pre> 107 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, "Value may not be NaN for object %s.", object); 108 * </pre> 109 * 110 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 111 * @param throwableClass the Throwable type to throw 112 * @param message the message to use in the exception, with formatting identifiers 113 * @param arg value to use for the formatting identifiers 114 * @throws T the throwable to throw on true condition 115 * @param <T> the Throwable type 116 */ 117 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, final String message, 118 final Object arg) throws T 119 { 120 if (condition) 121 { 122 List<Object> argList = new ArrayList<>(); 123 argList.add(arg); 124 throwMessage(throwableClass, message, argList); 125 } 126 } 127 128 /** 129 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 130 * follows: <br> 131 * 132 * <pre> 133 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, 134 * "Value may not be NaN for object %s with name %s.", object, name); 135 * </pre> 136 * 137 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 138 * @param throwableClass the Throwable type to throw 139 * @param message the message to use in the exception, with formatting identifiers 140 * @param arg1 1st value to use for the formatting identifiers 141 * @param arg2 2nd value to use for the formatting identifiers 142 * @throws T the throwable to throw on true condition 143 * @param <T> the Throwable type 144 */ 145 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, final String message, 146 final Object arg1, final Object arg2) throws T 147 { 148 if (condition) 149 { 150 List<Object> argList = new ArrayList<>(); 151 argList.add(arg1); 152 argList.add(arg2); 153 throwMessage(throwableClass, message, argList); 154 } 155 } 156 157 /** 158 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 159 * follows: <br> 160 * 161 * <pre> 162 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, 163 * "Value may not be NaN for object %s with name %s and id %s.", object, name, id); 164 * </pre> 165 * 166 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 167 * @param throwableClass the Throwable type to throw 168 * @param message the message to use in the exception, with formatting identifiers 169 * @param arg1 1st value to use for the formatting identifiers 170 * @param arg2 2nd value to use for the formatting identifiers 171 * @param arg3 3rd value to use for the formatting identifiers 172 * @throws T the throwable to throw on true condition 173 * @param <T> the Throwable type 174 */ 175 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, final String message, 176 final Object arg1, final Object arg2, final Object arg3) throws T 177 { 178 if (condition) 179 { 180 List<Object> argList = new ArrayList<>(); 181 argList.add(arg1); 182 argList.add(arg2); 183 argList.add(arg3); 184 throwMessage(throwableClass, message, argList); 185 } 186 } 187 188 /** 189 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. Use as 190 * follows: <br> 191 * 192 * <pre> 193 * Throw.when(Double.isNan(object.getValue()), IllegalArgumentException.class, 194 * "Value may not be NaN for object %s with name %s, id %s and parent %s.", object, name, id, parent); 195 * </pre> 196 * 197 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 198 * @param throwableClass the Throwable type to throw 199 * @param message the message to use in the exception, with formatting identifiers 200 * @param arg1 1st value to use for the formatting identifiers 201 * @param arg2 2nd value to use for the formatting identifiers 202 * @param arg3 3rd value to use for the formatting identifiers 203 * @param args potential 4th and further values to use for the formatting identifiers 204 * @throws T the throwable to throw on true condition 205 * @param <T> the Throwable type 206 */ 207 public static <T extends Throwable> void when(final boolean condition, final Class<T> throwableClass, final String message, 208 final Object arg1, final Object arg2, final Object arg3, final Object... args) throws T 209 { 210 if (condition) 211 { 212 List<Object> argList = new ArrayList<>(); 213 argList.add(arg1); 214 argList.add(arg2); 215 argList.add(arg3); 216 argList.addAll(Arrays.asList(args)); 217 throwMessage(throwableClass, message, argList); 218 } 219 } 220 221 /** 222 * Private method to handle the throwing an Exception, Throwable or Error. 223 * @param throwableClass the Throwable type to throw 224 * @param message the message to use in the exception, with potential formatting identifiers 225 * @param argList List with potential values to use for the formatting identifiers, or null when there are no formatting 226 * identifiers 227 * @throws T the throwable to throw 228 * @param <T> the Throwable type 229 */ 230 private static <T extends Throwable> void throwMessage(final Class<T> throwableClass, final String message, 231 final List<Object> argList) throws T 232 { 233 // create a clear message 234 List<StackTraceElement> steList = new ArrayList<>(Arrays.asList(new Throwable().getStackTrace())); 235 steList.remove(0); // remove the throwMessage(...) call 236 steList.remove(0); // remove the when(...) call 237 StackTraceElement[] ste = steList.toArray(new StackTraceElement[steList.size()]); 238 String where = ste[0].getClassName() + "." + ste[0].getMethodName() + " (" + ste[0].getLineNumber() + "): "; 239 String formattedMessage; 240 if (argList == null) 241 { 242 formattedMessage = message; 243 } 244 else 245 { 246 try 247 { 248 formattedMessage = where + String.format(message, argList.toArray()); 249 } 250 catch (IllegalFormatException exception) 251 { 252 formattedMessage = where + message + " [FormatException; args=" + argList + "]"; 253 } 254 } 255 256 // throw all other exceptions through reflection 257 T exception; 258 try 259 { 260 Constructor<T> constructor = ClassUtil.resolveConstructor(throwableClass, new Class<?>[] {String.class}); 261 exception = constructor.newInstance(formattedMessage); 262 exception.setStackTrace(ste); 263 } 264 catch (Throwable t) 265 { 266 RuntimeException rte = new RuntimeException(t.getMessage(), new Exception(formattedMessage)); 267 rte.setStackTrace(ste); 268 throw rte; 269 } 270 throw exception; 271 } 272 273 /** 274 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 275 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 276 * 277 * <pre> 278 * super(Throw.when(object, Double.isNaN(object.getValue()), IllegalArgumentException.class, "Value may not be NaN.")); 279 * </pre> 280 * 281 * @param object the object to return by this static method 282 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 283 * @param throwableClass the Throwable type to throw 284 * @param message the message to use in the exception 285 * @throws T the throwable to throw on true condition 286 * @param <T> the Throwable type 287 * @param <O> the Object type to return 288 * @return the object that was passed as the first parameter 289 */ 290 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 291 final Class<T> throwableClass, final String message) throws T 292 { 293 if (condition) 294 { 295 throwMessage(throwableClass, message, null); 296 } 297 return object; 298 } 299 300 /** 301 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 302 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 303 * 304 * <pre> 305 * super(Throw.when(object, object.isIncomplete(), IllegalArgumentException.class, () -> object.reportStatus())); 306 * </pre> 307 * 308 * @param object the object to return by this static method 309 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 310 * @param throwableClass the Throwable type to throw 311 * @param stringSupplier the supplier that provides the message to use in the exception 312 * @throws T the throwable to throw on true condition 313 * @param <T> the Throwable type 314 * @param <O> the Object type to return 315 * @return the object that was passed as the first parameter 316 */ 317 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 318 final Class<T> throwableClass, final Supplier<String> stringSupplier) throws T 319 { 320 if (condition) 321 { 322 throwMessage(throwableClass, stringSupplier.get(), null); 323 } 324 return object; 325 } 326 327 /** 328 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 329 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 330 * 331 * <pre> 332 * super(Throw.when(object, Double.isNan(object.getValue()), IllegalArgumentException.class, 333 * "Value may not be NaN for object %s.", object)); 334 * </pre> 335 * 336 * @param object the object to return by this static method 337 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 338 * @param throwableClass the Throwable type to throw 339 * @param message the message to use in the exception, with formatting identifiers 340 * @param arg value to use for the formatting identifiers 341 * @throws T the throwable to throw on true condition 342 * @param <T> the Throwable type 343 * @param <O> the Object type to return 344 * @return the object that was passed as the first parameter 345 */ 346 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 347 final Class<T> throwableClass, final String message, final Object arg) throws T 348 { 349 if (condition) 350 { 351 List<Object> argList = new ArrayList<>(); 352 argList.add(arg); 353 throwMessage(throwableClass, message, argList); 354 } 355 return object; 356 } 357 358 /** 359 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 360 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 361 * 362 * <pre> 363 * super(Throw.when(object, Double.isNan(object.getValue()), IllegalArgumentException.class, 364 * "Value may not be NaN for object %s with name %s.", object, name)); 365 * </pre> 366 * 367 * @param object the object to return by this static method 368 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 369 * @param throwableClass the Throwable type to throw 370 * @param message the message to use in the exception, with formatting identifiers 371 * @param arg1 1st value to use for the formatting identifiers 372 * @param arg2 2nd value to use for the formatting identifiers 373 * @throws T the throwable to throw on true condition 374 * @param <T> the Throwable type 375 * @param <O> the Object type to return 376 * @return the object that was passed as the first parameter 377 */ 378 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 379 final Class<T> throwableClass, final String message, final Object arg1, final Object arg2) throws T 380 { 381 if (condition) 382 { 383 List<Object> argList = new ArrayList<>(); 384 argList.add(arg1); 385 argList.add(arg2); 386 throwMessage(throwableClass, message, argList); 387 } 388 return object; 389 } 390 391 /** 392 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 393 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 394 * 395 * <pre> 396 * super(Throw.when(object, Double.isNan(object.getValue()), IllegalArgumentException.class, 397 * "Value may not be NaN for object %s with name %s and id %s.", object, name, id)); 398 * </pre> 399 * 400 * @param object the object to return by this static method 401 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 402 * @param throwableClass the Throwable type to throw 403 * @param message the message to use in the exception, with formatting identifiers 404 * @param arg1 1st value to use for the formatting identifiers 405 * @param arg2 2nd value to use for the formatting identifiers 406 * @param arg3 3rd value to use for the formatting identifiers 407 * @throws T the throwable to throw on true condition 408 * @param <T> the Throwable type 409 * @param <O> the Object type to return 410 * @return the object that was passed as the first parameter 411 */ 412 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 413 final Class<T> throwableClass, final String message, final Object arg1, final Object arg2, final Object arg3) 414 throws T 415 { 416 if (condition) 417 { 418 List<Object> argList = new ArrayList<>(); 419 argList.add(arg1); 420 argList.add(arg2); 421 argList.add(arg3); 422 throwMessage(throwableClass, message, argList); 423 } 424 return object; 425 } 426 427 /** 428 * Throw a Throwable (such as an Exception or Error) if a condition is met, e.g. for pre- and postcondition checking. This 429 * version of the method returns its first parameter, so it can be used inside a constructor. Use e.g., as follows: 430 * 431 * <pre> 432 * super(Throw.when(object, Double.isNan(object.getValue()), IllegalArgumentException.class, 433 * "Value may not be NaN for object %s with name %s, id %s and parent %s.", object, name, id, parent)); 434 * </pre> 435 * 436 * @param object the object to return by this static method 437 * @param condition the condition to check; an exception will be thrown if this is <b>true</b> 438 * @param throwableClass the Throwable type to throw 439 * @param message the message to use in the exception, with formatting identifiers 440 * @param arg1 1st value to use for the formatting identifiers 441 * @param arg2 2nd value to use for the formatting identifiers 442 * @param arg3 3rd value to use for the formatting identifiers 443 * @param args potential 4th and further values to use for the formatting identifiers 444 * @throws T the throwable to throw on true condition 445 * @param <T> the Throwable type 446 * @param <O> the Object type to return 447 * @return the object that was passed as the first parameter 448 */ 449 @SuppressWarnings("checkstyle:parameternumber") 450 public static <T extends Throwable, O extends Object> O when(final O object, final boolean condition, 451 final Class<T> throwableClass, final String message, final Object arg1, final Object arg2, final Object arg3, 452 final Object... args) throws T 453 { 454 if (condition) 455 { 456 List<Object> argList = new ArrayList<>(); 457 argList.add(arg1); 458 argList.add(arg2); 459 argList.add(arg3); 460 argList.addAll(Arrays.asList(args)); 461 throwMessage(throwableClass, message, argList); 462 } 463 return object; 464 } 465 466 /** 467 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 468 * 469 * <pre> 470 * Throw.whenNull(value, "value may not be null."); 471 * </pre> 472 * 473 * A shortened version where the text " may not be null" is automatically appended after the variable name is just listing 474 * the variable name without any spaces: 475 * 476 * <pre> 477 * Throw.whenNull(value, "value"); 478 * </pre> 479 * 480 * @param object an exception will be thrown if the object is <b>null</b> 481 * @param message the message to use in the exception, or the variable name that will be appended with " may not be null" 482 * @param <O> the Object type to return 483 * @return the object that was passed as the first parameter 484 * @throws NullPointerException if object is null 485 */ 486 public static <O extends Object> O whenNull(final O object, final String message) throws NullPointerException 487 { 488 if (object == null) 489 { 490 if (message.matches("\\S+")) // \S+ is any non-whitespace character 491 { 492 throwMessage(NullPointerException.class, message + " may not be null", null); 493 } 494 else 495 { 496 throwMessage(NullPointerException.class, message, null); 497 } 498 } 499 return object; 500 } 501 502 /** 503 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 504 * 505 * <pre> 506 * Throw.whenNull(value, () -> getLocalizedNullMessage()); 507 * </pre> 508 * 509 * @param object an exception will be thrown if the object is <b>null</b> 510 * @param stringSupplier the supplier that provides the message to use in the exception 511 * @param <O> the Object type to return 512 * @return the object that was passed as the first parameter 513 * @throws NullPointerException if object is null 514 */ 515 public static <O extends Object> O whenNull(final O object, final Supplier<String> stringSupplier) 516 throws NullPointerException 517 { 518 if (object == null) 519 { 520 throwMessage(NullPointerException.class, stringSupplier.get(), null); 521 } 522 return object; 523 } 524 525 /** 526 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 527 * 528 * <pre> 529 * Throw.whenNull(object.getValue(), "Value may not be null for object %s.", object); 530 * </pre> 531 * 532 * @param object an exception will be thrown if this is <b>null</b> 533 * @param message the message to use in the exception, with formatting identifiers 534 * @param arg value to use for the formatting identifiers 535 * @param <O> the Object type to return 536 * @return the object that was passed as the first parameter 537 * @throws NullPointerException if object is null 538 */ 539 public static <O extends Object> O whenNull(final O object, final String message, final Object arg) 540 throws NullPointerException 541 { 542 if (object == null) 543 { 544 List<Object> argList = new ArrayList<>(); 545 argList.add(arg); 546 throwMessage(NullPointerException.class, message, argList); 547 } 548 return object; 549 } 550 551 /** 552 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 553 * 554 * <pre> 555 * Throw.whenNull(object.getValue(), "Value may not be null for object %s with name %s.", object, name); 556 * </pre> 557 * 558 * @param object an exception will be thrown if this is <b>null</b> 559 * @param message the message to use in the exception, with formatting identifiers 560 * @param arg1 1st value to use for the formatting identifiers 561 * @param arg2 2nd value to use for the formatting identifiers 562 * @param <O> the Object type to return 563 * @return the object that was passed as the first parameter 564 * @throws NullPointerException if object is null 565 */ 566 public static <O extends Object> O whenNull(final O object, final String message, final Object arg1, final Object arg2) 567 throws NullPointerException 568 { 569 if (object == null) 570 { 571 List<Object> argList = new ArrayList<>(); 572 argList.add(arg1); 573 argList.add(arg2); 574 throwMessage(NullPointerException.class, message, argList); 575 } 576 return object; 577 } 578 579 /** 580 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 581 * 582 * <pre> 583 * Throw.whenNull(object.getValue(), "Value may not be null for object %s with name %s and id %s.", object, name, id); 584 * </pre> 585 * 586 * @param object an exception will be thrown if this is <b>null</b> 587 * @param message the message to use in the exception, with formatting identifiers 588 * @param arg1 1st value to use for the formatting identifiers 589 * @param arg2 2nd value to use for the formatting identifiers 590 * @param arg3 3rd value to use for the formatting identifiers 591 * @param <O> the Object type to return 592 * @return the object that was passed as the first parameter 593 * @throws NullPointerException if object is null 594 */ 595 public static <O extends Object> O whenNull(final O object, final String message, final Object arg1, final Object arg2, 596 final Object arg3) throws NullPointerException 597 { 598 if (object == null) 599 { 600 List<Object> argList = new ArrayList<>(); 601 argList.add(arg1); 602 argList.add(arg2); 603 argList.add(arg3); 604 throwMessage(NullPointerException.class, message, argList); 605 } 606 return object; 607 } 608 609 /** 610 * Throw a NullPointerException if object is null, e.g. for pre- and postcondition checking. Use as follows: <br> 611 * 612 * <pre> 613 * Throw.whenNull(object.getValue(), "Value may not be null for object %s with name %s, id %s and parent %s.", object, name, id, 614 * parent); 615 * </pre> 616 * 617 * @param object an exception will be thrown if this is <b>null</b> 618 * @param message the message to use in the exception, with formatting identifiers 619 * @param arg1 1st value to use for the formatting identifiers 620 * @param arg2 2nd value to use for the formatting identifiers 621 * @param arg3 3rd value to use for the formatting identifiers 622 * @param args potential 4th and further values to use for the formatting identifiers 623 * @param <O> the Object type to return 624 * @return the object that was passed as the first parameter 625 * @throws NullPointerException if object is null 626 */ 627 public static <O extends Object> O whenNull(final O object, final String message, final Object arg1, final Object arg2, 628 final Object arg3, final Object... args) throws NullPointerException 629 { 630 if (object == null) 631 { 632 List<Object> argList = new ArrayList<>(); 633 argList.add(arg1); 634 argList.add(arg2); 635 argList.add(arg3); 636 argList.addAll(Arrays.asList(args)); 637 throwMessage(NullPointerException.class, message, argList); 638 } 639 return object; 640 } 641 642 /** 643 * Throw a NullPointerException if any of the odd arguments is null, e.g. for pre- and postcondition checking. The message 644 * can consist of one identifier for the object, or a complete message. Use as follows: <br> 645 * 646 * <pre> 647 * Throw.whenAnyNull(alpha, "alpha", beta, "beta", calc, "the variable calc should not be null"); 648 * </pre> 649 * 650 * @param object the first object to check 651 * @param message the message or id of the first object to check 652 * @param objects objects to check on the odd positions, and messages or ids for the objects on the even positions 653 * @throws IllegalArgumentException when the number of arguments is not even 654 * @throws IllegalArgumentException when any of the messages is null 655 * @throws NullPointerException if any of the objects to be tested is null 656 */ 657 public static void whenAnyNull(final Object object, final String message, final Object... objects) 658 { 659 if ((objects.length & 1) == 1) 660 { 661 throw new IllegalArgumentException("Throw.whenAnyNull should have an even number of arguments"); 662 } 663 if (message == null) 664 { 665 throw new IllegalArgumentException("Throw.whenAnyNull should not have any null message"); 666 } 667 Throw.whenNull(object, message); 668 for (int i = 0; i < objects.length; i += 2) 669 { 670 if (objects[i + 1] == null) 671 { 672 throw new IllegalArgumentException("Throw.whenAnyNull should not have any null message"); 673 } 674 Throw.whenNull(objects[i], objects[i + 1].toString()); 675 } 676 } 677 678 /** 679 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 680 * 681 * <pre> 682 * Throw.whenNaN(value, "value may not be NaN."); 683 * </pre> 684 * 685 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 686 * the variable name without any spaces: 687 * 688 * <pre> 689 * Throw.whenNaN(value, "value"); 690 * </pre> 691 * 692 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 693 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 694 * @return the value that was passed as the first parameter 695 * @throws ArithmeticException if value is NaN 696 */ 697 public static double whenNaN(final double value, final String message) throws ArithmeticException 698 { 699 if (Double.isNaN(value)) 700 { 701 if (message.matches("\\S+")) // \S+ is any non-whitespace character 702 { 703 throwMessage(ArithmeticException.class, message + " may not be NaN", null); 704 } 705 else 706 { 707 throwMessage(ArithmeticException.class, message, null); 708 } 709 } 710 return value; 711 } 712 713 /** 714 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use e.g. as follows: <br> 715 * 716 * <pre> 717 * Throw.whenNaN(value, () -> getLocalizedNaNMessage()); 718 * </pre> 719 * 720 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 721 * @param stringSupplier the supplier that provides the message to use in the exception 722 * @return the value that was passed as the first parameter 723 * @throws ArithmeticException if value is NaN 724 */ 725 public static double whenNaN(final double value, final Supplier<String> stringSupplier) throws ArithmeticException 726 { 727 if (Double.isNaN(value)) 728 { 729 throwMessage(ArithmeticException.class, stringSupplier.get(), null); 730 } 731 return value; 732 } 733 734 /** 735 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 736 * 737 * <pre> 738 * Throw.whenNaN(value, "value may not be NaN."); 739 * </pre> 740 * 741 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 742 * the variable name without any spaces: 743 * 744 * <pre> 745 * Throw.whenNaN(value, "value"); 746 * </pre> 747 * 748 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 749 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 750 * @return the value that was passed as the first parameter 751 * @throws ArithmeticException if value is NaN 752 */ 753 public static float whenNaN(final float value, final String message) throws ArithmeticException 754 { 755 if (Float.isNaN(value)) 756 { 757 if (message.matches("\\S+")) // \S+ is any non-whitespace character 758 { 759 throwMessage(ArithmeticException.class, message + " may not be NaN", null); 760 } 761 else 762 { 763 throwMessage(ArithmeticException.class, message, null); 764 } 765 } 766 return value; 767 } 768 769 /** 770 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use e.g. as follows: <br> 771 * 772 * <pre> 773 * Throw.whenNaN(value, () -> getLocalizedNaNMessage()); 774 * </pre> 775 * 776 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 777 * @param stringSupplier the supplier that provides the message to use in the exception 778 * @return the value that was passed as the first parameter 779 * @throws ArithmeticException if value is NaN 780 */ 781 public static float whenNaN(final float value, final Supplier<String> stringSupplier) throws ArithmeticException 782 { 783 if (Float.isNaN(value)) 784 { 785 throwMessage(ArithmeticException.class, stringSupplier.get(), null); 786 } 787 return value; 788 } 789 790 /** 791 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 792 * 793 * <pre> 794 * Throw.whenNaN(value, "value may not be NaN."); 795 * </pre> 796 * 797 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 798 * the variable name without any spaces: 799 * 800 * <pre> 801 * Throw.whenNaN(value, "value"); 802 * </pre> 803 * 804 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 805 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 806 * @return the value that was passed as the first parameter 807 * @throws ArithmeticException if value is NaN 808 */ 809 public static Double whenNaN(final Double value, final String message) throws ArithmeticException 810 { 811 if (value != null && Double.isNaN(value)) 812 { 813 if (message.matches("\\S+")) // \S+ is any non-whitespace character 814 { 815 throwMessage(ArithmeticException.class, message + " may not be NaN", null); 816 } 817 else 818 { 819 throwMessage(ArithmeticException.class, message, null); 820 } 821 } 822 return value; 823 } 824 825 /** 826 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use e.g. as follows: <br> 827 * 828 * <pre> 829 * Throw.whenNaN(value, () -> getLocalizedNaNMessage()); 830 * </pre> 831 * 832 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 833 * @param stringSupplier the supplier that provides the message to use in the exception 834 * @return the value that was passed as the first parameter 835 * @throws ArithmeticException if value is NaN 836 */ 837 public static Double whenNaN(final Double value, final Supplier<String> stringSupplier) throws ArithmeticException 838 { 839 if (value != null && Double.isNaN(value)) 840 { 841 throwMessage(ArithmeticException.class, stringSupplier.get(), null); 842 } 843 return value; 844 } 845 846 /** 847 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 848 * 849 * <pre> 850 * Throw.whenNaN(value, "value may not be NaN."); 851 * </pre> 852 * 853 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 854 * the variable name without any spaces: 855 * 856 * <pre> 857 * Throw.whenNaN(value, "value"); 858 * </pre> 859 * 860 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 861 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 862 * @return the value that was passed as the first parameter 863 * @throws ArithmeticException if value is NaN 864 */ 865 public static Float whenNaN(final Float value, final String message) throws ArithmeticException 866 { 867 if (value != null && Float.isNaN(value)) 868 { 869 if (message.matches("\\S+")) // \S+ is any non-whitespace character 870 { 871 throwMessage(ArithmeticException.class, message + " may not be NaN", null); 872 } 873 else 874 { 875 throwMessage(ArithmeticException.class, message, null); 876 } 877 } 878 return value; 879 } 880 881 /** 882 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use e.g. as follows: <br> 883 * 884 * <pre> 885 * Throw.whenNaN(value, () -> getLocalizedNaNMessage()); 886 * </pre> 887 * 888 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 889 * @param stringSupplier the supplier that provides the message to use in the exception 890 * @return the value that was passed as the first parameter 891 * @throws ArithmeticException if value is NaN 892 */ 893 public static Float whenNaN(final Float value, final Supplier<String> stringSupplier) throws ArithmeticException 894 { 895 if (value != null && Float.isNaN(value)) 896 { 897 throwMessage(ArithmeticException.class, stringSupplier.get(), null); 898 } 899 return value; 900 } 901 902 /** 903 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 904 * 905 * <pre> 906 * Throw.whenNaN(value, "Value may not be NaN for object %s with name %s, id %s.", object, name, id); 907 * </pre> 908 * 909 * @param value the value to check; an exception will be thrown if this is <b>NaN</b> 910 * @param message the message to use in the exception, with formatting identifiers 911 * @param arg1 1st value to use for the formatting identifiers 912 * @param args potential 2nd and further values to use for the formatting identifiers 913 * @return the value that was passed as the first parameter 914 * @throws ArithmeticException if value is NaN 915 */ 916 public static Double whenNaN(final Double value, final String message, final Object arg1, final Object... args) 917 throws ArithmeticException 918 { 919 if (value != null && Double.isNaN(value)) 920 { 921 List<Object> argList = new ArrayList<>(); 922 argList.add(arg1); 923 argList.addAll(Arrays.asList(args)); 924 throwMessage(ArithmeticException.class, message, argList); 925 } 926 return value; 927 } 928 929 /** 930 * Throw an ArithmeticException if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 931 * 932 * <pre> 933 * Throw.whenNaN(value, "Value may not be NaN for object %s with name %s, id %s.", object, name, id); 934 * </pre> 935 * 936 * @param value the value to check; an exception will be thrown if this is <b>NaN</b> 937 * @param message the message to use in the exception, with formatting identifiers 938 * @param arg1 1st value to use for the formatting identifiers 939 * @param args potential 2nd and further values to use for the formatting identifiers 940 * @return the value that was passed as the first parameter 941 * @throws ArithmeticException if value is NaN 942 */ 943 public static Float whenNaN(final Float value, final String message, final Object arg1, final Object... args) 944 throws ArithmeticException 945 { 946 if (value != null && Float.isNaN(value)) 947 { 948 List<Object> argList = new ArrayList<>(); 949 argList.add(arg1); 950 argList.addAll(Arrays.asList(args)); 951 throwMessage(ArithmeticException.class, message, argList); 952 } 953 return value; 954 } 955 956 /** 957 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 958 * 959 * <pre> 960 * Throw.whenNaN(value, IllegalArgumentException.class, "value may not be NaN."); 961 * </pre> 962 * 963 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 964 * the variable name without any spaces: 965 * 966 * <pre> 967 * Throw.whenNaN(value, IllegalArgumentException.class, "value"); 968 * </pre> 969 * 970 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 971 * @param throwableClass the Throwable type to throw 972 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 973 * @param <T> the Throwable class 974 * @return the value that was passed as the first parameter 975 * @throws T if value is NaN 976 */ 977 public static <T extends Throwable> double whenNaN(final double value, final Class<T> throwableClass, final String message) 978 throws T 979 { 980 if (Double.isNaN(value)) 981 { 982 if (message.matches("\\S+")) // \S+ is any non-whitespace character 983 { 984 throwMessage(throwableClass, message + " may not be NaN", null); 985 } 986 else 987 { 988 throwMessage(throwableClass, message, null); 989 } 990 } 991 return value; 992 } 993 994 /** 995 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 996 * 997 * <pre> 998 * Throw.whenNaN(value, IllegalArgumentException.class, "value may not be NaN."); 999 * </pre> 1000 * 1001 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 1002 * the variable name without any spaces: 1003 * 1004 * <pre> 1005 * Throw.whenNaN(value, IllegalArgumentException.class, "value"); 1006 * </pre> 1007 * 1008 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1009 * @param throwableClass the Throwable type to throw 1010 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 1011 * @param <T> the Throwable class 1012 * @return the value that was passed as the first parameter 1013 * @throws T if value is NaN 1014 */ 1015 public static <T extends Throwable> float whenNaN(final float value, final Class<T> throwableClass, final String message) 1016 throws T 1017 { 1018 if (Float.isNaN(value)) 1019 { 1020 if (message.matches("\\S+")) // \S+ is any non-whitespace character 1021 { 1022 throwMessage(throwableClass, message + " may not be NaN", null); 1023 } 1024 else 1025 { 1026 throwMessage(throwableClass, message, null); 1027 } 1028 } 1029 return value; 1030 } 1031 1032 /** 1033 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1034 * 1035 * <pre> 1036 * Throw.whenNaN(value, IllegalArgumentException.class, () -> getLocalizedNaNMessage()); 1037 * </pre> 1038 * 1039 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1040 * @param throwableClass the Throwable type to throw 1041 * @param stringSupplier the supplier that provides the message to use in the exception 1042 * @param <T> the Throwable class 1043 * @return the value that was passed as the first parameter 1044 * @throws T if value is NaN 1045 */ 1046 public static <T extends Throwable> float whenNaN(final float value, final Class<T> throwableClass, 1047 final Supplier<String> stringSupplier) throws T 1048 { 1049 if (Float.isNaN(value)) 1050 { 1051 throwMessage(throwableClass, stringSupplier.get(), null); 1052 } 1053 return value; 1054 } 1055 1056 /** 1057 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1058 * 1059 * <pre> 1060 * Throw.whenNaN(value, IllegalArgumentException.class, "value may not be NaN."); 1061 * </pre> 1062 * 1063 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 1064 * the variable name without any spaces: 1065 * 1066 * <pre> 1067 * Throw.whenNaN(value, IllegalArgumentException.class, "value"); 1068 * </pre> 1069 * 1070 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1071 * @param throwableClass the Throwable type to throw 1072 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 1073 * @param <T> the Throwable class 1074 * @return the value that was passed as the first parameter 1075 * @throws T if value is NaN 1076 */ 1077 public static <T extends Throwable> Double whenNaN(final Double value, final Class<T> throwableClass, final String message) 1078 throws T 1079 { 1080 if (value != null && Double.isNaN(value)) 1081 { 1082 if (message.matches("\\S+")) // \S+ is any non-whitespace character 1083 { 1084 throwMessage(throwableClass, message + " may not be NaN", null); 1085 } 1086 else 1087 { 1088 throwMessage(throwableClass, message, null); 1089 } 1090 } 1091 return value; 1092 } 1093 1094 /** 1095 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1096 * 1097 * <pre> 1098 * Throw.whenNaN(value, IllegalArgumentException.class, () -> getLocalizedNaNMessage()); 1099 * </pre> 1100 * 1101 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1102 * @param throwableClass the Throwable type to throw 1103 * @param stringSupplier the supplier that provides the message to use in the exception 1104 * @param <T> the Throwable class 1105 * @return the value that was passed as the first parameter 1106 * @throws T if value is NaN 1107 */ 1108 public static <T extends Throwable> double whenNaN(final double value, final Class<T> throwableClass, 1109 final Supplier<String> stringSupplier) throws T 1110 { 1111 if (Double.isNaN(value)) 1112 { 1113 throwMessage(throwableClass, stringSupplier.get(), null); 1114 } 1115 return value; 1116 } 1117 1118 /** 1119 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1120 * 1121 * <pre> 1122 * Throw.whenNaN(value, IllegalArgumentException.class, () -> getLocalizedNaNMessage()); 1123 * </pre> 1124 * 1125 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1126 * @param throwableClass the Throwable type to throw 1127 * @param stringSupplier the supplier that provides the message to use in the exception 1128 * @param <T> the Throwable class 1129 * @return the value that was passed as the first parameter 1130 * @throws T if value is NaN 1131 */ 1132 public static <T extends Throwable> Double whenNaN(final Double value, final Class<T> throwableClass, 1133 final Supplier<String> stringSupplier) throws T 1134 { 1135 if (value != null && Double.isNaN(value)) 1136 { 1137 throwMessage(throwableClass, stringSupplier.get(), null); 1138 } 1139 return value; 1140 } 1141 1142 /** 1143 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1144 * 1145 * <pre> 1146 * Throw.whenNaN(value, IllegalArgumentException.class, "Value may not be NaN for object %s with name %s, 1147 * id %s.", object, name, id); 1148 * </pre> 1149 * 1150 * @param value the value to check; an exception will be thrown if this is <b>NaN</b> 1151 * @param throwableClass the Throwable type to throw 1152 * @param message the message to use in the exception, with formatting identifiers 1153 * @param arg1 1st value to use for the formatting identifiers 1154 * @param args potential 2nd and further values to use for the formatting identifiers 1155 * @param <T> the Throwable class 1156 * @return the value that was passed as the first parameter 1157 * @throws T if value is NaN 1158 */ 1159 public static <T extends Throwable> Double whenNaN(final Double value, final Class<T> throwableClass, final String message, 1160 final Object arg1, final Object... args) throws T 1161 { 1162 if (value != null && Double.isNaN(value)) 1163 { 1164 List<Object> argList = new ArrayList<>(); 1165 argList.add(arg1); 1166 argList.addAll(Arrays.asList(args)); 1167 throwMessage(throwableClass, message, argList); 1168 } 1169 return value; 1170 } 1171 1172 /** 1173 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1174 * 1175 * <pre> 1176 * Throw.whenNaN(value, IllegalArgumentException.class, "value may not be NaN."); 1177 * </pre> 1178 * 1179 * A shortened version where the text " may not be NaN" is automatically appended after the variable name is just listing 1180 * the variable name without any spaces: 1181 * 1182 * <pre> 1183 * Throw.whenNaN(value, IllegalArgumentException.class, "value"); 1184 * </pre> 1185 * 1186 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1187 * @param throwableClass the Throwable type to throw 1188 * @param message the message to use in the exception, or the variable name that will be appended with " may not be NaN" 1189 * @param <T> the Throwable class 1190 * @return the value that was passed as the first parameter 1191 * @throws T if value is NaN 1192 */ 1193 public static <T extends Throwable> Float whenNaN(final Float value, final Class<T> throwableClass, final String message) 1194 throws T 1195 { 1196 if (value != null && Float.isNaN(value)) 1197 { 1198 if (message.matches("\\S+")) // \S+ is any non-whitespace character 1199 { 1200 throwMessage(throwableClass, message + " may not be NaN", null); 1201 } 1202 else 1203 { 1204 throwMessage(throwableClass, message, null); 1205 } 1206 } 1207 return value; 1208 } 1209 1210 /** 1211 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1212 * 1213 * <pre> 1214 * Throw.whenNaN(value, IllegalArgumentException.class, () -> getLocalizedNaNMessage()); 1215 * </pre> 1216 * 1217 * @param value value to check; an exception will be thrown if the object is <b>NaN</b> 1218 * @param throwableClass the Throwable type to throw 1219 * @param stringSupplier the supplier that provides the message to use in the exception 1220 * @param <T> the Throwable class 1221 * @return the value that was passed as the first parameter 1222 * @throws T if value is NaN 1223 */ 1224 public static <T extends Throwable> Float whenNaN(final Float value, final Class<T> throwableClass, 1225 final Supplier<String> stringSupplier) throws T 1226 { 1227 if (value != null && Float.isNaN(value)) 1228 { 1229 throwMessage(throwableClass, stringSupplier.get(), null); 1230 } 1231 return value; 1232 } 1233 1234 /** 1235 * Throw a specified exception if value is NaN, e.g. for pre- and postcondition checking. Use as follows: <br> 1236 * 1237 * <pre> 1238 * Throw.whenNaN(value, IllegalArgumentException.class, "Value may not be NaN for object %s with name %s, 1239 * id %s.", object, name, id); 1240 * </pre> 1241 * 1242 * @param value the value to check; an exception will be thrown if this is <b>NaN</b> 1243 * @param throwableClass the Throwable type to throw 1244 * @param message the message to use in the exception, with formatting identifiers 1245 * @param arg1 1st value to use for the formatting identifiers 1246 * @param args potential 2nd and further values to use for the formatting identifiers 1247 * @param <T> the Throwable class 1248 * @return the value that was passed as the first parameter 1249 * @throws T if value is NaN 1250 */ 1251 public static <T extends Throwable> Float whenNaN(final Float value, final Class<T> throwableClass, final String message, 1252 final Object arg1, final Object... args) throws T 1253 { 1254 if (value != null && Float.isNaN(value)) 1255 { 1256 List<Object> argList = new ArrayList<>(); 1257 argList.add(arg1); 1258 argList.addAll(Arrays.asList(args)); 1259 throwMessage(throwableClass, message, argList); 1260 } 1261 return value; 1262 } 1263 1264 /** 1265 * Throw an unchecked exception for a method with a fixed signature (e.g., extending a method from a library that cannot be 1266 * changed), without having to declare the exception, which can be impossible when extending a method. The typical use is: 1267 * 1268 * <pre> 1269 * @Override 1270 * public void someMethod() { 1271 * try { 1272 * // some code that throws e.g., an IOException 1273 * } catch IOException e { 1274 * Throw.throwUnchecked(e); 1275 * } 1276 * } 1277 * </pre> 1278 * 1279 * From: <a href="http://blog.ragozin.info/2011/10/java-how-to-throw-undeclared-checked.html" target="_blank"> 1280 * http://blog.ragozin.info/2011/10/java-how-to-throw-undeclared-checked.html</a> as mentioned in <a href= 1281 * "https://stackoverflow.com/questions/11942946/how-to-throw-an-exception-when-your-method-signature-doesnt-allow-to-throw-exce" 1282 * target="_blank"> 1283 * https://stackoverflow.com/questions/11942946/how-to-throw-an-exception-when-your-method-signature-doesnt-allow-to-throw-exce</a>. 1284 * @param e the exception of Throwable to throw in an unchecked manner 1285 */ 1286 @SuppressWarnings("checkstyle:genericwhitespace") 1287 public static void throwUnchecked(final Throwable e) 1288 { 1289 Throw.<RuntimeException> throwAny(e); 1290 } 1291 1292 /** 1293 * @param <E> The exception class 1294 * @param e The throwable 1295 * @throws E The exception to throw 1296 */ 1297 @SuppressWarnings("unchecked") 1298 private static <E extends Throwable> void throwAny(final Throwable e) throws E 1299 { 1300 throw (E) e; 1301 } 1302 }