public class ThreadExceptions { private static void expect(boolean v) { if (! v) throw new RuntimeException("Expectation failed"); } private static class Handler implements Thread.UncaughtExceptionHandler { public String message; @Override public void uncaughtException(Thread t, Throwable e) { message = e.getMessage(); } } public static void main(String[] args) throws Exception { { Thread thread = new Thread() { @Override public void run() { throw new RuntimeException("TEST-DEFAULT-HANDLER"); } }; Handler handler = new Handler(); Thread.setDefaultUncaughtExceptionHandler(handler); thread.start(); thread.join(); expect("TEST-DEFAULT-HANDLER".equals(handler.message)); } Thread.setDefaultUncaughtExceptionHandler(null); { Thread thread = new Thread() { @Override public void run() { throw new RuntimeException("TEST-HANDLER"); } }; Handler handler = new Handler(); thread.setUncaughtExceptionHandler(handler); thread.start(); thread.join(); expect("TEST-HANDLER".equals(handler.message)); } { Thread thread = new Thread() { @Override public void run() { throw new RuntimeException("TEST-BAD-HANDLER"); } }; Handler handler = new Handler() { @Override public void uncaughtException(Thread t, Throwable e) { super.uncaughtException(t, e); throw new IllegalStateException("BAD THING"); } }; thread.setUncaughtExceptionHandler(handler); thread.start(); thread.join(); expect("TEST-BAD-HANDLER".equals(handler.message)); System.out.println("Exception from UncaughtExceptionHandler was ignored"); } } }