• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
SneakyThrow()56     private SneakyThrow() {
57     }
58 
sneakyThrow(Throwable t)59     public static void sneakyThrow(Throwable t) {
60         SneakyThrow.<Error>sneakyThrow2(t);
61     }
62 
63     /**
64      * Exploits unsafety to throw an exception that the compiler wouldn't permit
65      * but that the runtime doesn't check. See Java Puzzlers #43.
66      */
67     @SuppressWarnings("unchecked")
sneakyThrow2(Throwable t)68     private static <T extends Throwable> void sneakyThrow2(Throwable t) throws T {
69         throw (T) t;
70     }
71 }
72