Учебники

Java — исключения

Исключение (или исключительное событие) — это проблема, возникающая во время выполнения программы. Когда возникает исключение, нормальный поток программы прерывается, и программа / приложение прерывается ненормально, что не рекомендуется, поэтому эти исключения должны быть обработаны.

Исключение может возникнуть по многим различным причинам. Ниже приведены некоторые сценарии, где возникает исключение.

  • Пользователь ввел неверные данные.

  • Файл, который необходимо открыть, не найден.

  • Сетевое соединение было потеряно во время связи, или JVM исчерпала память.

Пользователь ввел неверные данные.

Файл, который необходимо открыть, не найден.

Сетевое соединение было потеряно во время связи, или JVM исчерпала память.

Некоторые из этих исключений вызваны ошибкой пользователя, другие — ошибкой программиста, а другие — физическими ресурсами, которые каким-то образом вышли из строя.

Исходя из этого, у нас есть три категории исключений. Вы должны понимать их, чтобы знать, как работает обработка исключений в Java.

  • Проверенные исключения — проверенное исключение — это исключение, которое проверяется (уведомляется) компилятором во время компиляции, они также называются исключениями во время компиляции. Эти исключения не могут быть просто проигнорированы, программист должен позаботиться об этих исключениях.

Проверенные исключения — проверенное исключение — это исключение, которое проверяется (уведомляется) компилятором во время компиляции, они также называются исключениями во время компиляции. Эти исключения не могут быть просто проигнорированы, программист должен позаботиться об этих исключениях.

Например, если вы используете класс FileReader в своей программе для чтения данных из файла, если файл, указанный в его конструкторе, не существует, возникает исключение FileNotFoundException , и компилятор предлагает программисту обработать исключение.

пример

Live Demo

import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {		
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

Если вы попытаетесь скомпилировать вышеуказанную программу, вы получите следующие исключения.

Выход

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

Примечание. Поскольку методы read () и close () класса FileReader выдают IOException, вы можете заметить, что компилятор уведомляет об обработке IOException вместе с FileNotFoundException.

  • Непроверенные исключения — непроверенное исключение — это исключение, которое возникает во время выполнения. Они также называются исключениями времени выполнения . К ним относятся ошибки программирования, такие как логические ошибки или неправильное использование API. Исключения во время выполнения игнорируются во время компиляции.

Непроверенные исключения — непроверенное исключение — это исключение, которое возникает во время выполнения. Они также называются исключениями времени выполнения . К ним относятся ошибки программирования, такие как логические ошибки или неправильное использование API. Исключения во время выполнения игнорируются во время компиляции.

Например, если вы объявили массив размером 5 в своей программе и пытаетесь вызвать 6- й элемент массива, возникает исключение ArrayIndexOutOfBoundsExceptionexception .

пример

Live Demo

public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

Если вы скомпилируете и запустите вышеуказанную программу, вы получите следующее исключение.

Выход

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
  • Ошибки — это вовсе не исключения, а проблемы, которые возникают вне контроля пользователя или программиста. Ошибки обычно игнорируются в вашем коде, потому что вы редко можете что-либо сделать с ошибкой. Например, если переполнение стека происходит, возникнет ошибка. Они также игнорируются во время компиляции.

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

Иерархия исключений

Все классы исключений являются подтипами класса java.lang.Exception. Класс исключения является подклассом класса Throwable. Помимо класса исключений, существует другой подкласс с именем Error, который является производным от класса Throwable.

Ошибки — это ненормальные условия, которые случаются в случае серьезных сбоев, они не обрабатываются программами Java. Ошибки генерируются для указания ошибок, генерируемых средой выполнения. Пример: JVM не хватает памяти. Обычно программы не могут восстановиться после ошибок.

Класс Exception имеет два основных подкласса: класс IOException и класс RuntimeException.

Exceptions1

Ниже приведен список наиболее распространенных проверенных и непроверенных встроенных исключений Java .

Методы исключений

Ниже приведен список важных методов, доступных в классе Throwable.

Sr.No. Метод и описание
1

public String getMessage ()

Возвращает подробное сообщение об исключении, которое произошло. Это сообщение инициализируется в конструкторе Throwable.

2

public Throwable getCause ()

Возвращает причину исключения в виде объекта Throwable.

3

public String toString ()

Возвращает имя класса, объединенного с результатом getMessage ().

4

public void printStackTrace ()

Печатает результат toString () вместе с трассировкой стека в System.err, поток вывода ошибок.

5

public StackTraceElement [] getStackTrace ()

Возвращает массив, содержащий каждый элемент в трассировке стека. Элемент с индексом 0 представляет вершину стека вызовов, а последний элемент в массиве представляет метод в нижней части стека вызовов.

6

public Throwable fillInStackTrace ()

Заполняет трассировку стека этого объекта Throwable текущей трассировкой стека, добавляя к любой предыдущей информации в трассировке стека.

public String getMessage ()

Возвращает подробное сообщение об исключении, которое произошло. Это сообщение инициализируется в конструкторе Throwable.

public Throwable getCause ()

Возвращает причину исключения в виде объекта Throwable.

public String toString ()

Возвращает имя класса, объединенного с результатом getMessage ().

public void printStackTrace ()

Печатает результат toString () вместе с трассировкой стека в System.err, поток вывода ошибок.

public StackTraceElement [] getStackTrace ()

Возвращает массив, содержащий каждый элемент в трассировке стека. Элемент с индексом 0 представляет вершину стека вызовов, а последний элемент в массиве представляет метод в нижней части стека вызовов.

public Throwable fillInStackTrace ()

Заполняет трассировку стека этого объекта Throwable текущей трассировкой стека, добавляя к любой предыдущей информации в трассировке стека.

Ловить исключения

Метод перехватывает исключение, используя комбинацию ключевых слов try и catch . Вокруг кода помещается блок try / catch, который может генерировать исключение. Код в блоке try / catch называется защищенным кодом, и синтаксис использования try / catch выглядит следующим образом:

Синтаксис

try {
   // Protected code
} catch (ExceptionName e1) {
   // Catch block
}

Код, подверженный исключениям, помещается в блок try. Когда возникает исключение, то возникшее исключение обрабатывается блоком catch, связанным с ним. За каждым блоком try должен немедленно следовать либо блок catch, либо блок finally.

Оператор catch включает объявление типа исключения, которое вы пытаетесь перехватить. Если в защищенном коде возникает исключение, проверяется блок catch (или блоки), следующий за попыткой. Если тип возникшего исключения указан в блоке catch, то исключение передается в блок catch так же, как аргумент передается в параметр метода.

пример

Ниже приведен массив, объявленный с 2 ​​элементами. Затем код пытается получить доступ к третьему элементу массива, который вызывает исключение.

Live Demo

// File Name : ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

Это даст следующий результат —

Выход

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

Многократные Пойманные Блоки

За блоком try могут следовать несколько блоков catch. Синтаксис для нескольких блоков catch выглядит следующим образом:

Синтаксис

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}

Предыдущие операторы демонстрируют три блока catch, но вы можете иметь любое их количество после одной попытки. Если в защищенном коде возникает исключение, оно генерируется в первом блоке перехвата в списке. Если тип данных сгенерированного исключения совпадает с ExceptionType1, он попадает туда. Если нет, то исключение передается во второй оператор catch. Это продолжается до тех пор, пока исключение не будет перехвачено или не пройдет через все перехваты, и в этом случае текущий метод останавливает выполнение, а исключение генерируется до предыдущего метода в стеке вызовов.

пример

Вот фрагмент кода, показывающий, как использовать несколько операторов try / catch.

try {
   file = new FileInputStream(fileName);
   x = (byte) file.read();
} catch (IOException i) {
   i.printStackTrace();
   return -1;
} catch (FileNotFoundException f) // Not valid! {
   f.printStackTrace();
   return -1;
}

Поймать несколько типов исключений

Начиная с Java 7, вы можете обрабатывать более одного исключения, используя один блок catch, эта функция упрощает код. Вот как бы вы это сделали —

catch (IOException|FileNotFoundException ex) {
   logger.log(ex);
   throw ex;

Ключевые слова Броски / Бросок

Если метод не обрабатывает проверенное исключение, метод должен объявить его с помощью ключевого слова throws . Ключевое слово throws появляется в конце подписи метода.

С помощью ключевого слова throw вы можете сгенерировать исключение, либо только что созданное, либо исключение, которое вы только что перехватили.

Попытайтесь понять разницу между ключевыми словами throw и throw, throw используется для того, чтобы отложить обработку проверенного исключения, а throw используется для явного вызова исключения.

Следующий метод объявляет, что он генерирует RemoteException —

пример

import java.io.*;
public class className {

   public void deposit(double amount) throws RemoteException {
      // Method implementation
      throw new RemoteException();
   }
   // Remainder of class definition
}

Метод может объявить, что он генерирует более одного исключения, и в этом случае исключения объявляются в списке, разделенном запятыми. Например, следующий метод объявляет, что он генерирует исключение RemoteException и InsufficientFundsException —

пример

import java.io.*;
public class className {

   public void withdraw(double amount) throws RemoteException, 
      InsufficientFundsException {
      // Method implementation
   }
   // Remainder of class definition
}

Последний блок

Блок finally следует за блоком try или блоком catch. Блок кода finally всегда выполняется независимо от возникновения исключения.

Использование блока finally позволяет запускать любые операторы типа очистки, которые вы хотите выполнить, независимо от того, что происходит в защищенном коде.

Блок finally появляется в конце блоков catch и имеет следующий синтаксис:

Синтаксис

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}finally {
   // The finally block always executes.
}

пример

Live Demo

public class ExcepTest {

   public static void main(String args[]) {
      int a[] = new int[2];
      try {
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }finally {
         a[0] = 6;
         System.out.println("First element value: " + a[0]);
         System.out.println("The finally statement is executed");
      }
   }
}

Это даст следующий результат —

Выход

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

Обратите внимание на следующее —

  • Предложение catch не может существовать без оператора try.

  • Не обязательно иметь предложения finally, когда присутствует блок try / catch.

  • Блок try не может присутствовать без предложения catch или оператора finally.

  • Никакой код не может присутствовать между блоками try, catch, finally.

Предложение catch не может существовать без оператора try.

Не обязательно иметь предложения finally, когда присутствует блок try / catch.

Блок try не может присутствовать без предложения catch или оператора finally.

Никакой код не может присутствовать между блоками try, catch, finally.

Попробуй с ресурсами

Как правило, когда мы используем какие-либо ресурсы, такие как потоки, соединения и т. Д., Мы должны явно закрывать их, используя блок finally. В следующей программе мы читаем данные из файла, используя FileReader, и закрываем его, используя блок finally.

пример

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;		
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // reads the content to the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            fr.close();
         } catch (IOException ex) {		
            ex.printStackTrace();
         }
      }
   }
}

try-with-resources , также называемый автоматическим управлением ресурсами , — это новый механизм обработки исключений, представленный в Java 7, который автоматически закрывает ресурсы, используемые в блоке try catch.

Чтобы использовать этот оператор, вам просто нужно объявить необходимые ресурсы в круглых скобках, и созданный ресурс будет автоматически закрыт в конце блока. Ниже приводится синтаксис оператора try-with-resources.

Синтаксис

try(FileReader fr = new FileReader("file path")) {
   // use the resource
   } catch () {
      // body of catch 
   }
}

Ниже приведена программа, которая считывает данные в файл с помощью оператора try-with-resources.

пример

import java.io.FileReader;
import java.io.IOException;

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // reads the contentto the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Следующие пункты должны быть учтены при работе с оператором try-with-resources.

  • Чтобы использовать класс с оператором try-with-resources, он должен реализовывать интерфейс AutoCloseable, и метод close () этого метода вызывается автоматически во время выполнения.

  • Вы можете объявить более одного класса в инструкции try-with-resources.

  • Хотя вы объявляете несколько классов в блоке try оператора try-with-resources, эти классы закрываются в обратном порядке.

  • За исключением объявления ресурсов в скобках, все совпадает с нормальным блоком try / catch блока try.

  • Ресурс, объявленный в try, создается непосредственно перед началом блока try.

  • Ресурс, объявленный в блоке try, неявно объявляется как final.

Чтобы использовать класс с оператором try-with-resources, он должен реализовывать интерфейс AutoCloseable, и метод close () этого метода вызывается автоматически во время выполнения.

Вы можете объявить более одного класса в инструкции try-with-resources.

Хотя вы объявляете несколько классов в блоке try оператора try-with-resources, эти классы закрываются в обратном порядке.

За исключением объявления ресурсов в скобках, все совпадает с нормальным блоком try / catch блока try.

Ресурс, объявленный в try, создается непосредственно перед началом блока try.

Ресурс, объявленный в блоке try, неявно объявляется как final.

Пользовательские исключения

Вы можете создавать свои собственные исключения в Java. При написании ваших собственных классов исключений помните следующее:

  • Все исключения должны быть детьми Throwable.

  • Если вы хотите написать проверенное исключение, которое автоматически применяется правилом Handle или Declare, вам необходимо расширить класс Exception.

  • Если вы хотите написать исключение времени выполнения, вам нужно расширить класс RuntimeException.

Все исключения должны быть детьми Throwable.

Если вы хотите написать проверенное исключение, которое автоматически применяется правилом Handle или Declare, вам необходимо расширить класс Exception.

Если вы хотите написать исключение времени выполнения, вам нужно расширить класс RuntimeException.

Мы можем определить наш собственный класс исключения, как показано ниже:

class MyException extends Exception {
}

Вам просто нужно расширить предопределенный класс Exception, чтобы создать собственное исключение. Они считаются проверенными исключениями. Следующий класс InsufficientFundsException является определяемым пользователем исключением, которое расширяет класс Exception, делая его проверенным исключением. Класс исключений, как и любой другой класс, содержит полезные поля и методы.

пример

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception {
   private double amount;
   
   public InsufficientFundsException(double amount) {
      this.amount = amount;
   }
   
   public double getAmount() {
      return amount;
   }
}

Чтобы продемонстрировать использование нашего пользовательского исключения, следующий класс CheckingAccount содержит методdraw (), который выдает исключение InsufficientFundsException.

// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount {
   private double balance;
   private int number;
   
   public CheckingAccount(int number) {
      this.number = number;
   }
   
   public void deposit(double amount) {
      balance += amount;
   }
   
   public void withdraw(double amount) throws InsufficientFundsException {
      if(amount <= balance) {
         balance -= amount;
      }else {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   
   public double getBalance() {
      return balance;
   }
   
   public int getNumber() {
      return number;
   }
}

Следующая программа BankDemo демонстрирует вызов методов depositing () иdraw () в CheckingAccount.

// File Name BankDemo.java
public class BankDemo {

   public static void main(String [] args) {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      
      try {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      } catch (InsufficientFundsException e) {
         System.out.println("Sorry, but you are short $" + e.getAmount());
         e.printStackTrace();
      }
   }
}

Скомпилируйте все три вышеуказанных файла и запустите BankDemo. Это даст следующий результат —

Выход

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
         at CheckingAccount.withdraw(CheckingAccount.java:25)
         at BankDemo.main(BankDemo.java:13)

Распространенные исключения

В Java можно определить две категории исключений и ошибок.

Исключения JVM — это исключения / ошибки, которые генерируются исключительно или логически JVM. Примеры: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.

Программные исключения — эти исключения явно генерируются приложением или программистами API. Примеры: IllegalArgumentException, IllegalStateException.