Lets consider following sample:

[code lang=”java”]
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(”throw ” + a.getName());
throw (T)e;
} else if (b.isAssignableFrom(e.getClass())) {
System.out.println(”throw ” + b.getName());
throw (E)e;
}

System.out.println(”throw runtime”);
throw new RuntimeException(e);
}

static String test(int x) throws FooException, BarException {
try {
if (x == 0) {
throw new FooException();
}
if (x == 1) {
throw new BarException();
}
if (x == 2) {
throw new Exception(”goatch”);
}
return ”DONE-” + x;
} catch (Throwable e) {
return rethrow(e, BarException.class, FooException.class);
}
}

public static void call(int x) {
try {
String t = test(x);
System.out.println(”RESULT=” + t);
} catch (FooException e) {
System.out.println(”foo”);
e.printStackTrace();
} catch (BarException e) {
System.out.println(”bar”);
e.printStackTrace();
} catch (Exception e) {
System.out.println(”OTHER”);
e.printStackTrace();
}
}

public static void main(String[] args ){
call(0);
call(1);
call(2);
call(3);
}
}
[/code]

Compile and run:
[code]
javac Test.java && java Test
[/code]

And end result is this:
[code]
throw Test$FooException
foo
Test$FooException
at Test.test(Test.java:37)
at Test.call(Test.java:54)
at Test.main(Test.java:68)
throw Test$BarException
bar
Test$BarException
at Test.test(Test.java:40)
at Test.call(Test.java:54)
at Test.main(Test.java:69)
throw runtime
OTHER
java.lang.RuntimeException: java.lang.Exception: goatch
at Test.rethrow(Test.java:19)
at Test.test(Test.java:47)
at Test.call(Test.java:54)
at Test.main(Test.java:70)
Caused by: java.lang.Exception: goatch
at Test.test(Test.java:43)
… 2 more
RESULT=DONE-3
[/code]

What the heck that means? Well it means magic. Basically it allows catching arbitrary exception and then rethrowing it with approriate typing. In normal application code there ain’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’s possible to sensible typed exception throwing from generic code.

Example of such framework
[code lang=”java”]
public abstract class TX {
public T start(Class e) throws KnonwException, E {
… private framework logic
}
public abstract Object run() throws Exception;
}

// And usage is something like this
try {
new TX() {
public Object run() throws Exception() {
throws new IOExcecption();
}
}.start(IOExcecption.class);
} catch (KnownException e) {
// easy; framework throws this always
} catch (IOException e) {
// magic; typed catch using generics
} catch (RuntimeException e) {
// without magic; this would be only only
// alternative to KnownException
}
[/code]

/ java

Vastaa

Sähköpostiosoitettasi ei julkaista.

This site uses Akismet to reduce spam. Learn how your comment data is processed.