Код, принятый валидатором:
import java.util.TimerTask;
public class Solution extends TimerTask {
protected TimerTask original;
protected final Thread.UncaughtExceptionHandler handler;
public Solution(TimerTask original) {
if (original == null) {
throw new NullPointerException();
}
this.original = original;
this.handler = new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(e.getMessage().replaceAll(t.getName(), t.getName().replaceAll(".","*")));
}
};
}
public void run() {
try {
original.run();
} catch (Throwable cause) {
Thread currentThread = Thread.currentThread();
handler.uncaughtException(currentThread, new Exception("Blah " + currentThread.getName() + " blah-blah-blah", cause));
}
}
public long scheduledExecutionTime() {
return original.scheduledExecutionTime();
}
public boolean cancel() {
return original.cancel();
}
public static void main(String[] args) {
Solution solution = new Solution(new TimerTask() {
@Override
public void run() {
throw new RuntimeException();
}
});
solution.run();
}
}
В main создаём объект solution. Во время создания происходит две вещи:
1. В конструкторе создаём нить handler = new Thread.UncaughtExceptionHandler() , которая ничего не делает до поры до времени.
2. Переопределяем функцию run в анонимном классе для созданного объекта.
Когда запускаем solution.run(); наш метод бросает исключение RuntimeException, а дальше уходит в метод run класса solution, где проскакивает try { original.run(); и уходит в catch (Throwable cause)
Поясните, почему цепочка уходит в тот метод run класса solution?, а не сразу в метод uncaughtException ?
Roman
33 уровень
Объясните пошагово, как это работает?
Решен
Комментарии (4)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
hidden #598481
10 марта 2022, 17:21
1. В конструкторе создаём нить handler = new Thread.UncaughtExceptionHandler() , которая ничего не делает до поры до времени.
Почему нить? Это не нить, это хэндлер, то есть штука, которая срабатывает, если в нити случится необработанное исключение. Ты в анонимном классе определяешь, что делать с этими исключениями и говоришь, что у объектов Солюшена будет этот хэндлер.
В мейне ты создаёшь и запускаешь объект Солюшен, который при выполнении выбрасывает исключение и наблюдаешь, как отрабатывает хэндлер твоего объекта.
0
Roman
11 марта 2022, 09:21
Привет. Спасибо за ответ. Я не понимаю вот какой нюанс. Как только выбрасывается исключение, дебаггер переходит в метод Solution.run(). Почему? Чем вызывается этот метод? А уже пройдя метод Solution.run() дебаггер идёт в метод uncaughtException, хотя, как я понимаю, должен идти в него сразу.
0
hidden #598481
11 марта 2022, 10:08
У тебя всё происходит в одном потоке.
Вот последняя команда в методе main:
Содержимое аргумента в конструкторе твоего Solution, вот это вот: - это просто реализация твоего таймертаска, который хранится в поле original. Итак, в мейне 2 действия:
1) создали солюшен
2) вызвали у него run
Вот он run. Выполняем команду original.run(). Содержимое original.run() мы задали при создании солюшена:выкидываем исключение
Solution.run отлавливает это исключение, срабатывает кетч. В кетче обращение к хендлеру:
+1
Roman
11 марта 2022, 10:08
упс. вопрос снят. Разобрался. Спасибо.
0