The design rationale for the run() method not throwing exceptions is because there is no calling context that could handle the exception.
Put another way, where in class
Test could you put a try/catch block that would catch the exceptions thrown by run(), given that the run() method is never invoked by Test? From the programmer's perspective, run() is invoked as if by magic.
What you have to do in this situation is implement a producer/consumer type
pattern, where the thread calls back to its creator to report its completion status.