{"id":377,"date":"2012-09-18T20:31:44","date_gmt":"2012-09-18T18:31:44","guid":{"rendered":"https:\/\/kari.world.ikari.fi\/?p=377"},"modified":"2012-09-18T20:31:44","modified_gmt":"2012-09-18T18:31:44","slug":"advanced-exception-throwing","status":"publish","type":"post","link":"https:\/\/kari.world.ikari.fi\/?p=377","title":{"rendered":"Advanced Exception Throwing"},"content":{"rendered":"<p>Lets consider following sample:<\/p>\n<p>[code lang=&#8221;java&#8221;]<br \/>\npublic class Test {<br \/>\nstatic class FooException extends Exception {<br \/>\n}<br \/>\nstatic class BarException extends Exception {<br \/>\n}<\/p>\n<p>static <T extends Throwable, E extends Throwable, Z> Z rethrow(Throwable e, Class<T> a, Class<E>  b)<br \/>\n        throws T, E<br \/>\n{<br \/>\n        if (a.isAssignableFrom(e.getClass())) {<br \/>\n                System.out.println(&#8221;throw &#8221; + a.getName());<br \/>\n                throw (T)e;<br \/>\n        } else if (b.isAssignableFrom(e.getClass())) {<br \/>\n                System.out.println(&#8221;throw &#8221; + b.getName());<br \/>\n                throw (E)e;<br \/>\n        }<\/p>\n<p>        System.out.println(&#8221;throw runtime&#8221;);<br \/>\n        throw new RuntimeException(e);<br \/>\n}<\/p>\n<p>static String test(int x) throws FooException, BarException {<br \/>\n    try {<br \/>\n        if (x  == 0) {<br \/>\n                throw new FooException();<br \/>\n        }<br \/>\n        if (x  == 1) {<br \/>\n                throw new BarException();<br \/>\n        }<br \/>\n        if (x  == 2) {<br \/>\n                throw new Exception(&#8221;goatch&#8221;);<br \/>\n        }<br \/>\n        return &#8221;DONE-&#8221; + x;<br \/>\n    } catch (Throwable e) {<br \/>\n        return rethrow(e, BarException.class, FooException.class);<br \/>\n    }<br \/>\n}<\/p>\n<p>public static void call(int x) {<br \/>\n    try {<br \/>\n        String t = test(x);<br \/>\n        System.out.println(&#8221;RESULT=&#8221; + t);<br \/>\n    } catch (FooException e) {<br \/>\n        System.out.println(&#8221;foo&#8221;);<br \/>\n        e.printStackTrace();<br \/>\n    } catch (BarException e) {<br \/>\n        System.out.println(&#8221;bar&#8221;);<br \/>\n        e.printStackTrace();<br \/>\n    } catch (Exception e) {<br \/>\n        System.out.println(&#8221;OTHER&#8221;);<br \/>\n        e.printStackTrace();<br \/>\n    }<br \/>\n}<\/p>\n<p>public static void main(String[] args ){<br \/>\n    call(0);<br \/>\n    call(1);<br \/>\n    call(2);<br \/>\n    call(3);<br \/>\n}<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>Compile and run:<br \/>\n[code]<br \/>\njavac Test.java &#038;&#038; java Test<br \/>\n[\/code]<\/p>\n<p>And end result is this:<br \/>\n[code]<br \/>\nthrow Test$FooException<br \/>\nfoo<br \/>\nTest$FooException<br \/>\n        at Test.test(Test.java:37)<br \/>\n        at Test.call(Test.java:54)<br \/>\n        at Test.main(Test.java:68)<br \/>\nthrow Test$BarException<br \/>\nbar<br \/>\nTest$BarException<br \/>\n        at Test.test(Test.java:40)<br \/>\n        at Test.call(Test.java:54)<br \/>\n        at Test.main(Test.java:69)<br \/>\nthrow runtime<br \/>\nOTHER<br \/>\njava.lang.RuntimeException: java.lang.Exception: goatch<br \/>\n        at Test.rethrow(Test.java:19)<br \/>\n        at Test.test(Test.java:47)<br \/>\n        at Test.call(Test.java:54)<br \/>\n        at Test.main(Test.java:70)<br \/>\nCaused by: java.lang.Exception: goatch<br \/>\n        at Test.test(Test.java:43)<br \/>\n        &#8230; 2 more<br \/>\nRESULT=DONE-3<br \/>\n[\/code]<\/p>\n<p>What the heck that means? Well it means <strong>magic<\/strong>. Basically it allows catching arbitrary exception and then rethrowing it with approriate typing. In normal application code there ain&#8217;t naturally any use for such, but when you consider that there could be generic framework piece, which allows passing in typing of throws clause, then it&#8217;s possible to sensible typed exception throwing from generic code.<\/p>\n<p>Example of such framework<br \/>\n[code lang=&#8221;java&#8221;]<br \/>\npublic abstract class TX {<br \/>\n    public <T, E extends Throwable> T start(Class<E> e) throws KnonwException, E {<br \/>\n         &#8230; private framework logic<br \/>\n    }<br \/>\n    public abstract Object run() throws Exception;<br \/>\n}<\/p>\n<p>&#8230;<\/p>\n<p>\/\/ And usage is something like this<br \/>\ntry {<br \/>\n    new TX() {<br \/>\n         public Object run() throws Exception() {<br \/>\n              throws new IOExcecption();<br \/>\n         }<br \/>\n    }.start(IOExcecption.class);<br \/>\n} catch (KnownException e) {<br \/>\n    \/\/ easy; framework throws this always<br \/>\n} catch (IOException e) {<br \/>\n    \/\/ magic; typed catch using generics<br \/>\n} catch (RuntimeException e) {<br \/>\n    \/\/ without magic; this would be only only<br \/>\n    \/\/ alternative to KnownException<br \/>\n}<br \/>\n[\/code]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lets consider following sample: [code lang=&#8221;java&#8221;] public class Test { static class FooException extends Exception { } static class BarException extends Exception { } static Z rethrow(Throwable e, Class a, Class b) throws T, E { if (a.isAssignableFrom(e.getClass())) { System.out.println(&#8221;throw &#8221; + a.getName()); throw (T)e; } else if (b.isAssignableFrom(e.getClass())) { System.out.println(&#8221;throw &#8221; + b.getName()); throw&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-377","post","type-post","status-publish","format-standard","hentry","category-java"],"_links":{"self":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts\/377","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377"}],"version-history":[{"count":0,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions"}],"wp:attachment":[{"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kari.world.ikari.fi\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}