Java перехватывает непроверенные исключения — использование UncaughtExceptionHandler

Java задняя часть программист переводчик
Java перехватывает непроверенные исключения — использование UncaughtExceptionHandler

смотрю сегодняZookeeperКогда исходный код был найден, он был использован в его исходном коде.UncaughtExceptionHandlerКлюч к обработке непроверенных исключений заключается в том, что я не знал об этом, когда впервые начал смотреть! Так что надо учиться! Итак, появляется следующее.

1. Типы исключений в Java

Это общая схема системы исключений Java:

Вообще говоря, в Java есть два типа исключений:

  • 1. Непроверенные исключения

    Непроверенное исключениеErrorиRuntimeExceptionи его подклассы,javacВо время компиляции такие исключения не запрашиваются и не обнаруживаются, и нет необходимости обрабатывать эти исключения в программе. Итак, если мы хотим, мы можем написать код для обработки (используяtry…catch…finally) такое исключение не может быть обработано. Для этих исключений мы должны исправить код, а не использовать обработчик исключений. Причиной такого исключения чаще всего является проблема с написанием кода. если кроме0ОшибкаArithmeticException, ошибка плохого приведенияClassCastException, индекс массива выходит за пределыArrayIndexOutOfBoundsExceptionИспользование нулевого объектаNullPointerExceptionи т.д

  • 2. Проверьте на исключения

    Проверенные исключения кромеErrorиRuntimeExceptionдругие исключения. javac заставляет программиста готовиться к таким исключениям (используяtry…catch…finallyилиthrows). Либо поймайте его с помощью оператора try-catch в методе и обработайте его, либо используйтеthrowsПредложение объявляет его бросать, иначе компиляция не пройдет. Такие исключения обычно вызваны операционной средой программы. Поскольку программа может запускаться в различных неизвестных средах, и программист не может вмешиваться в то, как пользователь использует написанную им программу, программист должен быть готов к такому нештатному моменту. какSQLException , IOException,ClassNotFoundExceptionЖдать.

Обобщить:

  • 1. Можно использовать проверенные исключения и непроверенные исключения.try…catch…finallyисключение перехвата блока
  • 2. Непроверенные исключения являются исключениями времени выполнения, и компилятор не предложит вам их перехватить.

Почему я делаю резюме? Я расскажу об этом ниже!

Во-вторых, использование UncaughtExceptionHandler

Много раз после того, как мы напишем код, мы всегда будем сообщать об исключении нулевого указателя после запуска, но мы не понимаем, что должны его перехватывать. Особенно в многопоточной среде класс потокаThreadизrun()Метод не генерирует никакой информации об исключении, если вrun()В методе сообщается об исключении нулевого указателя, но мы его не перехватываем, следствием будет прерывание потока, а прерывание потока может быть не тем результатом, который мы хотим видеть.

Больше всего раздражает то, что информация об исключении, генерируемая дочерним потоком, не может быть захвачена в его основном потоке. Следующий пример демонстрирует:

public class NoCaughtThread {

public static void main(String[] args) {
	// 捕获不到
	try {
		Thread thread = new Thread(new Task());
		thread.start();
	} catch (Exception e) {
		e.printStackTrace();
	}
    }
}

class Task implements Runnable {

@Override
public void run() {
	throw new NullPointerException();
    }
}

Результат работы программы:

Exception in thread "Thread-0" java.lang.NullPointerException
	at org.apache.zookeeper.server.quorum.Task.run(NoCaughtThread.java:21)
	at java.lang.Thread.run(Unknown Source)

Чтобы обрабатывать эти необработанные исключения, jdk поставляется сUncaughtExceptionHandlerclass для обработки, примеры следующие:

import java.lang.Thread.UncaughtExceptionHandler;

public class NoCaughtThread {

public static void main(String[] args) {
	// 设置未捕获异常处理器,这里是默认的,当然你可以自己新建一个类,然后实现UncaughtExceptionHandler接口即可
	Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {

		@Override
		public void uncaughtException(Thread t, Throwable e) {
			System.err.println("程序抛出了一个异常,异常类型为 : " + e);
		}
	});
	Thread thread = new Thread(new Task());
	thread.start();
    }
}

class Task implements Runnable {

@Override
public void run() {
	throw new NullPointerException();
    }
}

Вывод программы:

程序抛出了一个异常,异常类型为 : java.lang.NullPointerException

3. Резюме

Подводя итог, в конечном счете, я думаю, причина, по которой нам нужно использоватьUncaughtExceptionHandler, Во многих случаях это происходит из-за того, что наш собственный код написан недостаточно хорошо, недостаточно строго или мы не вдумчивы при написании кода. Например, наиболее распространенным является выбрасывание нулевого указателя.NullPointerException, см. код ниже:

Map<String, String> map = null;
System.err.println(map.get("name"));

Приведенный выше код должен генерировать исключение NullPointerException, вы можете сказать, вау, кто такой глупый, настолько очевидныйmap=null, ну, чтобы убедить вас, я решил щелкнуть пальцами:

// 从数据库查找一个用户
User user = userDao.getUser(12);
System.err.println(user.getUserName("name"));

Видно, что еслиuserзаnull, он также должен вызывать исключение нулевого указателя. Нам нужно как можно больше избегать многих и многих непроверенных исключений.При написании кода мы должны учитывать, будет ли нулевой указатель, будет ли массив за пределами и так далее.