1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package libcore.util; 19 20 /** 21 * Exploits a weakness in the runtime to throw an arbitrary throwable without 22 * the traditional declaration. <strong>This is a dangerous API that should be 23 * used with great caution.</strong> Typically this is useful when rethrowing 24 * throwables that are of a known range of types. 25 * 26 * <p>The following code must enumerate several types to rethrow: 27 * <pre> 28 * public void close() throws IOException { 29 * Throwable thrown = null; 30 * ... 31 * 32 * if (thrown != null) { 33 * if (thrown instanceof IOException) { 34 * throw (IOException) thrown; 35 * } else if (thrown instanceof RuntimeException) { 36 * throw (RuntimeException) thrown; 37 * } else if (thrown instanceof Error) { 38 * throw (Error) thrown; 39 * } else { 40 * throw new AssertionError(); 41 * } 42 * } 43 * }</pre> 44 * With SneakyThrow, rethrowing is easier: 45 * <pre> 46 * public void close() throws IOException { 47 * Throwable thrown = null; 48 * ... 49 * 50 * if (thrown != null) { 51 * SneakyThrow.sneakyThrow(thrown); 52 * } 53 * }</pre> 54 */ 55 public final class SneakyThrow { 56 private SneakyThrow() {} 57 58 public static void sneakyThrow(Throwable t) { 59 SneakyThrow.<Error>sneakyThrow2(t); 60 } 61 62 /** 63 * Exploits unsafety to throw an exception that the compiler wouldn't permit 64 * but that the runtime doesn't check. See Java Puzzlers #43. 65 */ 66 @SuppressWarnings("unchecked") 67 private static <T extends Throwable> void sneakyThrow2(Throwable t) throws T { 68 throw (T) t; 69 } 70 } 71