English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В этом руководстве мы изучим обработку исключений с помощью ключевых слов throw и throws на примерах.
В Java исключения можно разделить на два типа:
Необработанные исключения:Они проверяются не на этапе компиляции, а на этапе выполнения, например: ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, исключения подкласса Error и т.д.
Проверенные исключения:Проверяйте их при компиляции. Например, IOException, InterruptedException и т.д.
См. такжеJava исключенияПодробнее о проверенных и непроверенных исключениях.
Обычно, нам не нужно обрабатывать необработанные исключения. Это связано с тем, что необработанные исключения возникают из-за ошибок в программировании. И лучше их исправлять, чем обрабатывать.
Теперь в этом руководстве мы сосредоточимся на том, как использовать throw и throws для обработки проверенных исключений.
Мы используем ключевое слово throws в объявлении метода для указания типов исключений, которые могут возникнуть.
Синтаксис:
accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 … { // code }
Из вышеуказанной синтаксической структуры можно увидеть, что мы можем использовать throws для объявления нескольких исключений.
import java.io.*; class Main { public static void findFile() throws IOException { // может вызвать IOException код File newFile = new File("test.txt"); FileInputStream stream = new FileInputStream(newFile); } public static void main(String[] args) { try{ findFile(); } catch(IOException e){ System.out.println(e); } } }
Результат вывода
java.io.FileNotFoundException: test.txt (нет такого файла или каталога)
Когда мы запускаем эту программу, если файл test.txt не существует, FileInputStream выбрасывает исключение FileNotFoundException, наследующее класс IOException.
Если метод не обрабатывает исключения, то必须在 разделе throws указать типы исключений, которые могут возникнуть в этом методе, чтобы более высокие уровни вызова в стеке вызовов могли обрабатывать их или использовать ключевое слово throws само по себе.
Метод findFile() указывает, что может быть выброшен IOException. Метод main() вызывает этот метод и обрабатывает выброшенные исключения.
Это метод, который использует ключевое слово throws для вызова нескольких исключений.
import java.io.*; class Main { public static void findFile() throws NullPointerException, IOException, InvalidClassException { // может вызвать NullPointerException код … … … // может вызвать IOException код … … … // может вызвать InvalidClassException код … … … } public static void main(String[] args) { try{ findFile(); catch(IOException e1){ System.out.println(e1.getMessage()); } catch(InvalidClassException e2) { System.out.println(e2.getMessage()); } } }
Здесь метод findFile() указывает, что он может выбрасывать NullPointerException, IOException и InvalidClassException в своем предложении throws.
Обратите внимание, что мы еще не обработали NullPointerException. Это потому, что это непроверяемое исключение. Не нужно указывать его в предложении throws и обрабатывать.
Может быть несколько методов, которые вызывают исключение. Написание try...catch для каждого метода будет утомительным, и код станет длинным и сложным для понимания.
Когда вы уже проверили исключение, которое не хотите捕获 в текущем методе (необязательное исключение), throws также полезно.
Ключевое слово throw используется для явного выбрасывания исключения.
Когда вызывается исключение, поток выполнения программы переходит от блока try к блоку catch. Мы используем ключевое слово throw в методе.
Синтаксис:
throw throwableObject;
Объект Throwable - это экземпляр класса Throwable или подкласса Throwable.
class Main { public static void divideByZero() { throw new ArithmeticException("попытка деления на ноль"); } public static void main(String[] args) { divideByZero(); } }
Результат вывода
Exception in thread "main" java.lang.ArithmeticException: попытка деления на ноль at Main.divideByZero(Main.java:3) at Main.main(Main.java:7) exit status 1
В этом примере мы явно выбрасываем ArithmeticException.
Внимание: ArithmeticException - это непроверяемое исключение. Обычно нет необходимости обрабатывать непроверяемые исключения.
import java.io.*; class Main { public static void findFile() throws IOException { throw new IOException("Файл не найден"); } public static void main(String[] args) { try { findFile(); System.out.println("Остальная часть кода в блоке try"); } System.out.println(e.getMessage()); } } }
Результат вывода
Файл не найден
Метод findFile() выбрасывает IOException, передавая сообщение в его конструктор.
Обратите внимание, что, поскольку это проверяемое исключение, его необходимо указать в предложении throws.
Метод, вызываемый методом findFile(), должен обрабатывать это исключение или指定 его с помощью ключевого слова throws.
Мы уже обработали это исключение в методе main(). При возникновении исключения поток выполнения программы перемещается между блоками try и catch. Таким образом, пропускается остальная часть кода в блоке try, и выполняются инструкции в блоке catch.