Меню

Ошибки времени выполнения java

Error is an illegal operation performed by the user which results in the abnormal working of the program. Programming errors often remain undetected until the program is compiled or executed. Some of the errors inhibit the program from getting compiled or executed. Thus errors should be removed before compiling and executing. 

The most common errors can be broadly classified as follows:

1. Run Time Error: 

Run Time errors occur or we can say, are detected during the execution of the program. Sometimes these are discovered when the user enters an invalid data or data which is not relevant. Runtime errors occur when a program does not contain any syntax errors but asks the computer to do something that the computer is unable to reliably do. During compilation, the compiler has no technique to detect these kinds of errors. It is the JVM (Java Virtual Machine) that detects it while the program is running. To handle the error during the run time we can put our error code inside the try block and catch the error inside the catch block. 

For example: if the user inputs a data of string format when the computer is expecting an integer, there will be a runtime error. Example 1: Runtime Error caused by dividing by zero 

Java

class DivByZero {

    public static void main(String args[])

    {

        int var1 = 15;

        int var2 = 5;

        int var3 = 0;

        int ans1 = var1 / var2;

        int ans2 = var1 / var3;

        System.out.println(

            "Division of va1"

            + " by var2 is: "

            + ans1);

        System.out.println(

            "Division of va1"

            + " by var3 is: "

            + ans2);

    }

}

Runtime Error in java code:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at DivByZero.main(File.java:14)

Example 2: Runtime Error caused by Assigning/Retrieving Value from an array using an index which is greater than the size of the array 

Java

class RTErrorDemo {

    public static void main(String args[])

    {

        int arr[] = new int[5];

        arr[9] = 250;

        System.out.println("Value assigned! ");

    }

}

RunTime Error in java code:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
    at RTErrorDemo.main(File.java:10)

2. Compile Time Error: 

Compile Time Errors are those errors which prevent the code from running because of an incorrect syntax such as a missing semicolon at the end of a statement or a missing bracket, class not found, etc. These errors are detected by the java compiler and an error message is displayed on the screen while compiling. Compile Time Errors are sometimes also referred to as Syntax errors. These kind of errors are easy to spot and rectify because the java compiler finds them for you. The compiler will tell you which piece of code in the program got in trouble and its best guess as to what you did wrong. Usually, the compiler indicates the exact line where the error is, or sometimes the line just before it, however, if the problem is with incorrectly nested braces, the actual error may be at the beginning of the block. In effect, syntax errors represent grammatical errors in the use of the programming language. 

Example 1: Misspelled variable name or method names 

Java

class MisspelledVar {

    public static void main(String args[])

    {

        int a = 40, b = 60;

        int Sum = a + b;

        System.out.println(

            "Sum of variables is "

            + sum);

    }

}

Compilation Error in java code:

prog.java:14: error: cannot find symbol
            + sum);
              ^
  symbol:   variable sum
  location: class MisspelledVar
1 error

Example 2: Missing semicolons 

Java

class PrintingSentence {

    public static void main(String args[])

    {

        String s = "GeeksforGeeks";

        System.out.println("Welcome to " + s)

    }

}

Compilation Error in java code:

prog.java:8: error: ';' expected
        System.out.println("Welcome to " + s)
                                             ^
1 error

Example: Missing parenthesis, square brackets, or curly braces 

Java

class MissingParenthesis {

    public static void main(String args[])

    {

        System.out.println("Printing 1 to 5 n");

        int i;

        for (i = 1; i <= 5; i++ {

            System.out.println(i + "n");

        }

    }

}

Compilation Error in java code:

prog.java:10: error: ')' expected
        for (i = 1; i <= 5; i++ {
                               ^
1 error

Example: Incorrect format of selection statements or loops 

Java

class IncorrectLoop {

    public static void main(String args[])

    {

        System.out.println("Multiplication Table of 7");

        int a = 7, ans;

        int i;

        for (i = 1, i <= 10; i++) {

            ans = a * i;

            System.out.println(ans + "n");

        }

    }

}

Compilation Error in java code:

prog.java:12: error: not a statement
        for (i = 1, i <= 10; i++) {
                      ^
prog.java:12: error: ';' expected
        for (i = 1, i <= 10; i++) {
                                ^
2 errors

Logical Error: A logic error is when your program compiles and executes, but does the wrong thing or returns an incorrect result or no output when it should be returning an output. These errors are detected neither by the compiler nor by JVM. The Java system has no idea what your program is supposed to do, so it provides no additional information to help you find the error. Logical errors are also called Semantic Errors. These errors are caused due to an incorrect idea or concept used by a programmer while coding. Syntax errors are grammatical errors whereas, logical errors are errors arising out of an incorrect meaning. For example, if a programmer accidentally adds two variables when he or she meant to divide them, the program will give no error and will execute successfully but with an incorrect result. 

Example: Accidentally using an incorrect operator on the variables to perform an operation (Using ‘/’ operator to get the modulus instead using ‘%’) 

Java

public class LErrorDemo {

    public static void main(String[] args)

    {

        int num = 789;

        int reversednum = 0;

        int remainder;

        while (num != 0) {

            remainder = num / 10;

            reversednum

                = reversednum * 10

                  + remainder;

            num /= 10;

        }

        System.out.println("Reversed number is "

                           + reversednum);

    }

}

Output:

Reversed number is 7870

Example: Displaying the wrong message 

Java

class IncorrectMessage {

    public static void main(String args[])

    {

        int a = 2, b = 8, c = 6;

        System.out.println(

            "Finding the largest number n");

        if (a > b && a > c)

            System.out.println(

                a + " is the largest Number");

        else if (b > a && b > c)

            System.out.println(

                b + " is the smallest Number");

        else

            System.out.println(

                c + " is the largest Number");

    }

}

Output:

Finding the largest number 

8 is the smallest Number

Syntax Error:

Syntax and Logical errors are faced by Programmers.

Spelling or grammatical mistakes are syntax errors, for example, using an uninitialized variable, using an undefined variable, etc., missing a semicolon, etc.

int x, y;
x = 10 // missing semicolon (;)
z = x + y; // z is undefined, y in uninitialized.

Syntax errors can be removed with the help of the compiler.

Error is an illegal operation performed by the user which results in the abnormal working of the program. Programming errors often remain undetected until the program is compiled or executed. Some of the errors inhibit the program from getting compiled or executed. Thus errors should be removed before compiling and executing. 

The most common errors can be broadly classified as follows:

1. Run Time Error: 

Run Time errors occur or we can say, are detected during the execution of the program. Sometimes these are discovered when the user enters an invalid data or data which is not relevant. Runtime errors occur when a program does not contain any syntax errors but asks the computer to do something that the computer is unable to reliably do. During compilation, the compiler has no technique to detect these kinds of errors. It is the JVM (Java Virtual Machine) that detects it while the program is running. To handle the error during the run time we can put our error code inside the try block and catch the error inside the catch block. 

For example: if the user inputs a data of string format when the computer is expecting an integer, there will be a runtime error. Example 1: Runtime Error caused by dividing by zero 

Java

class DivByZero {

    public static void main(String args[])

    {

        int var1 = 15;

        int var2 = 5;

        int var3 = 0;

        int ans1 = var1 / var2;

        int ans2 = var1 / var3;

        System.out.println(

            "Division of va1"

            + " by var2 is: "

            + ans1);

        System.out.println(

            "Division of va1"

            + " by var3 is: "

            + ans2);

    }

}

Runtime Error in java code:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at DivByZero.main(File.java:14)

Example 2: Runtime Error caused by Assigning/Retrieving Value from an array using an index which is greater than the size of the array 

Java

class RTErrorDemo {

    public static void main(String args[])

    {

        int arr[] = new int[5];

        arr[9] = 250;

        System.out.println("Value assigned! ");

    }

}

RunTime Error in java code:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
    at RTErrorDemo.main(File.java:10)

2. Compile Time Error: 

Compile Time Errors are those errors which prevent the code from running because of an incorrect syntax such as a missing semicolon at the end of a statement or a missing bracket, class not found, etc. These errors are detected by the java compiler and an error message is displayed on the screen while compiling. Compile Time Errors are sometimes also referred to as Syntax errors. These kind of errors are easy to spot and rectify because the java compiler finds them for you. The compiler will tell you which piece of code in the program got in trouble and its best guess as to what you did wrong. Usually, the compiler indicates the exact line where the error is, or sometimes the line just before it, however, if the problem is with incorrectly nested braces, the actual error may be at the beginning of the block. In effect, syntax errors represent grammatical errors in the use of the programming language. 

Example 1: Misspelled variable name or method names 

Java

class MisspelledVar {

    public static void main(String args[])

    {

        int a = 40, b = 60;

        int Sum = a + b;

        System.out.println(

            "Sum of variables is "

            + sum);

    }

}

Compilation Error in java code:

prog.java:14: error: cannot find symbol
            + sum);
              ^
  symbol:   variable sum
  location: class MisspelledVar
1 error

Example 2: Missing semicolons 

Java

class PrintingSentence {

    public static void main(String args[])

    {

        String s = "GeeksforGeeks";

        System.out.println("Welcome to " + s)

    }

}

Compilation Error in java code:

prog.java:8: error: ';' expected
        System.out.println("Welcome to " + s)
                                             ^
1 error

Example: Missing parenthesis, square brackets, or curly braces 

Java

class MissingParenthesis {

    public static void main(String args[])

    {

        System.out.println("Printing 1 to 5 n");

        int i;

        for (i = 1; i <= 5; i++ {

            System.out.println(i + "n");

        }

    }

}

Compilation Error in java code:

prog.java:10: error: ')' expected
        for (i = 1; i <= 5; i++ {
                               ^
1 error

Example: Incorrect format of selection statements or loops 

Java

class IncorrectLoop {

    public static void main(String args[])

    {

        System.out.println("Multiplication Table of 7");

        int a = 7, ans;

        int i;

        for (i = 1, i <= 10; i++) {

            ans = a * i;

            System.out.println(ans + "n");

        }

    }

}

Compilation Error in java code:

prog.java:12: error: not a statement
        for (i = 1, i <= 10; i++) {
                      ^
prog.java:12: error: ';' expected
        for (i = 1, i <= 10; i++) {
                                ^
2 errors

Logical Error: A logic error is when your program compiles and executes, but does the wrong thing or returns an incorrect result or no output when it should be returning an output. These errors are detected neither by the compiler nor by JVM. The Java system has no idea what your program is supposed to do, so it provides no additional information to help you find the error. Logical errors are also called Semantic Errors. These errors are caused due to an incorrect idea or concept used by a programmer while coding. Syntax errors are grammatical errors whereas, logical errors are errors arising out of an incorrect meaning. For example, if a programmer accidentally adds two variables when he or she meant to divide them, the program will give no error and will execute successfully but with an incorrect result. 

Example: Accidentally using an incorrect operator on the variables to perform an operation (Using ‘/’ operator to get the modulus instead using ‘%’) 

Java

public class LErrorDemo {

    public static void main(String[] args)

    {

        int num = 789;

        int reversednum = 0;

        int remainder;

        while (num != 0) {

            remainder = num / 10;

            reversednum

                = reversednum * 10

                  + remainder;

            num /= 10;

        }

        System.out.println("Reversed number is "

                           + reversednum);

    }

}

Output:

Reversed number is 7870

Example: Displaying the wrong message 

Java

class IncorrectMessage {

    public static void main(String args[])

    {

        int a = 2, b = 8, c = 6;

        System.out.println(

            "Finding the largest number n");

        if (a > b && a > c)

            System.out.println(

                a + " is the largest Number");

        else if (b > a && b > c)

            System.out.println(

                b + " is the smallest Number");

        else

            System.out.println(

                c + " is the largest Number");

    }

}

Output:

Finding the largest number 

8 is the smallest Number

Syntax Error:

Syntax and Logical errors are faced by Programmers.

Spelling or grammatical mistakes are syntax errors, for example, using an uninitialized variable, using an undefined variable, etc., missing a semicolon, etc.

int x, y;
x = 10 // missing semicolon (;)
z = x + y; // z is undefined, y in uninitialized.

Syntax errors can be removed with the help of the compiler.

Чтобы разобраться, в чем разница между ошибками времени компиляции и ошибками времени выполнения в Java, разберемся в сути каждого вида.

Ошибки времени компиляции

Это синтаксические ошибки в коде, которые препятствуют его компиляции.

Пример

public class Test{
   public static void main(String args[]){
      System.out.println("Hello")
   }
}

Итог

C:Sample>Javac Test.java
Test.java:3: error: ';' expected
   System.out.println("Hello")

Ошибки времени выполнения

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

Пример

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

A runtime error in Java is an application error that occurs during the execution of a program. A runtime error occurs when a program is syntactically correct but contains an issue that is only detected during program execution. These issues cannot be caught at compile-time by the Java compiler and are only detected by the Java Virtual Machine (JVM) when the application is running.

Runtime errors are a category of exception that contains several more specific error types. Some of the most common types of runtime errors are:

  • IO errors
  • Division by zero errors
  • Out of range errors
  • Undefined object errors

Runtime Errors vs Compile-Time Errors

Compile-time errors occur when there are syntactical issues present in application code, for example, missing semicolons or parentheses, misspelled keywords or usage of undeclared variables.

These syntax errors are detected by the Java compiler at compile-time and an error message is displayed on the screen. The compiler prevents the code from being executed until the error is fixed. Therefore, these errors must be addressed by debugging before the program can be successfully run.

On the other hand, runtime errors occur during program execution (the interpretation phase), after compilation has taken place. Any code that throws a runtime error is therefore syntactically correct.

Runtime Errors vs Logical Errors

A runtime error could potentially be a legitimate issue in code, for example, incorrectly formatted input data or lack of resources (e.g. insufficient memory or disk space). When a runtime error occurs in Java, the compiler specifies the lines of code where the error is encountered. This information can be used to trace back where the problem originated.

On the other hand, a logical error is always the symptom of a bug in application code leading to incorrect output e.g. subtracting two variables instead of adding them. In case of a logical error, the program operates incorrectly but does not terminate abnormally. Each statement may need to be checked to identify a logical error, which makes it generally harder to debug than a runtime error.

What Causes Runtime Errors in Java

The most common causes of runtime errors in Java are:

  • Dividing a number by zero.
  • Accessing an element in an array that is out of range.
  • Attempting to store an incompatible type value to a collection.
  • Passing an invalid argument to a method.
  • Attempting to convert an invalid string to a number.
  • Insufficient space in memory for thread data.

When any such errors are encountered, the Java compiler generates an error message and terminates the program abnormally. Runtime errors don’t need to be explicitly caught and handled in code. However, it may be useful to catch them and continue program execution.

To handle a runtime error, the code can be placed within a try-catch block and the error can be caught inside the catch block.

Runtime Error Examples

Division by zero error

Here is an example of a java.lang.ArithmeticException, a type of runtime exception, thrown due to division by zero:

public class ArithmeticExceptionExample {
public static void main(String[] args) {
          int a = 10, b = 0;
          System.out.println("Result: "+ a/b);
    }
}

In this example, an integer a is attempted to be divided by another integer b, whose value is zero, leading to a java.lang.ArithmeticException:

Exception in thread "main" java.lang.ArithmeticException: / by zero
        at ArithmeticExceptionExample.main(ArithmeticExceptionExample.java:4)

Accessing an out of range value in an array

Here is an example of a java.lang.ArrayIndexOutOfBoundsExceptionthrown due to an attempt to access an element in an array that is out of bounds:

public class ValueOutOfRangeErrorExample {
    public static void main(String[] args) {
        int arr[] = new int[5];
        System.out.println("5th element in array: " + arr[5]);
    }
}

In this example, an array is initialized with 5 elements. An element at position 5 is later attempted to be accessed in the array, which does not exist, leading to a java.lang.ArrayIndexOutOfBoundsException runtime error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at ValueOutOfRangeErrorExample.main(ValueOutOfRangeErrorExample.java:4)

How to Solve Runtime Errors

Runtime errors can be handled in Java using try-catch blocks with the following steps:

  • Surround the statements that can throw a runtime error in try-catch blocks.
  • Catch the error.
  • Depending on the requirements of the application, take necessary action. For example, log the exception with an appropriate message.

To illustrate this, the code in the earlier ArithmeticException example can be updated with the above steps:

public class ArithmeticExceptionExample {
    public static void main(String[] args) {
        try {
            int a = 10, b = 0;
            System.out.println("Result: " + a/b);
        } catch (ArithmeticException ae) {
            System.out.println("Arithmetic Exception: cannot divide by 0");
        }
        System.out.println("Continuing execution...");
    }
}

Surrounding the code in try-catch blocks like the above allows the program to continue execution after the exception is encountered:

Arithmetic Exception: cannot divide by 0
Continuing execution…

Runtime errors can be avoided where possible by paying attention to detail and making sure all statements in code are mathematically and logically correct.

Track, Analyze and Manage Errors With Rollbar

![Rollbar in action](https://rollbar.com/wp-content/uploads/2022/04/section-1-real-time-errors@2x-1-300×202.png)

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing errors easier than ever. Try it today.

1. Чтобы различать ошибки времени компиляции и ошибки времени выполнения, вы должны сначала понять, что такое компиляция? Что работает?
Сначала взгляните на эту картинку:

Период компиляции — это процесс передачи исходного кода Java, который мы написали компилятору для выполнения.переводРоль этого процесса в основномПроверьте синтаксис исходного кода Java, Если нет синтаксических ошибок, скомпилируйте исходный код в файл байт-кода (т.е. файл класса)
Среда выполнения — это процесс загрузки файла байт-кода (файла .class) в память и передачи его на виртуальную машину Java до конца выполнения программы.Проверьте логические ошибки программыЕсли логической ошибки нет, функция программы реализуется и результат выводится.
2. Различия в распределении памяти между компиляцией и временем выполнения
time Время компиляции — только для генерации некоторой оперативной памяти управляющей программы в файле байт-кода программы.инструкцияПростоKnowРазмер выделения памяти и место хранения,Нет конкретной операции выделения
② Время выполнения — это памятьРеальное распределениеОпределите память, выделенную программойразмерИ эти переменные должны храниться в памятирасположение
3. При разработке java-проекта в Eclipse, как отличить ошибку компиляции от ошибки времени выполнения?
errors Ошибки компиляции обычно относятся к синтаксическим ошибкам или очевидным логическим ошибкам.
Например: отсутствие точки с запятой, меньше скобок, неправильное написание ключевых слов и т. д., часто рисуют красные линии в затмении.
error Ошибка операции — это логическая ошибка, сгенерированная после запуска на основе ошибки компиляции.
Например: исключение нулевого указателя, делитель 0, доступ за пределы допустимого и т. д., как правило, вызывает исключение.
4. Примеры
Следующая программа, отредактируйте и запустите, результат ()

public class Test{
           public void main(String[] args){
                      System.out.println("Hello world");
                      }
              }

Результат:Компилировать без ошибок, новремя выполненияПроизошло исключение.

На чтение 2 мин. Просмотров 5 Опубликовано 25.05.2021

Рассмотрим следующий сегмент кода Java, хранящийся в файле с именем JollyMessage.java:

 
//На экран выводится веселое сообщение! 
class Jollymessage
{

public static void main (String [] args) {

//Записываем сообщение в окно терминала
System.out.println ("Ho Ho Ho!");

}
}

При выполнении программы этот код выдаст сообщение об ошибке выполнения. Другими словами, где-то была допущена ошибка, но ошибка не будет идентифицирована, когда программа скомпилирована , только когда она запущена .

Отладка

В приведенном выше примере обратите внимание, что класс называется «Jollymessage», а имя файла – JollyMessage.java .

Java чувствительна к регистру. Компилятор не будет жаловаться, потому что технически с кодом все в порядке. Он создаст файл класса, который точно соответствует имени класса (например, Jollymessage.class). Когда вы запустите программу под названием JollyMessage, вы получите сообщение об ошибке, потому что нет файла с именем JollyMessage.class.

Ошибка, которую вы получаете при запуске программа с неправильным именем:

 
 Исключение в потоке «main» java.lang.NoClassDefFoundError: JollyMessage (неверно  name: JollyMessage) .. 

Общие решения для ошибок во время выполнения

Если ваша программа успешно компилируется, но не выполняется, проверьте код для типичных ошибок:

  • Несоответствующие одинарные и двойные кавычки
  • Отсутствующие кавычки для строк
  • Неправильные операторы сравнения (например, отсутствие двойных знаков равенства для обозначения присваивания)
  • Ссылка на несуществующие или несуществующие объекты с использованием заглавных букв, указанных в коде
  • Ссылка на объект, не имеющий свойств

Работа в интегрированных средах разработки, таких как Eclipse, может помочь вам избежать Ошибки в стиле «опечатка».

Для отладки промышленных программ Java запустите отладчик веб-браузера – вы должны увидеть сообщение об ошибке в шестнадцатеричном формате, которое может помочь изолировать конкретная причина проблемы.

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

Зміст

  • Что такое исключение в Java (Java Exception)?
  • Операторы try, catch, finally, throw, throws: обработка исключений и примеры использования
  • Иерархия исключений Java
  • Заключение

Что такое исключение в Java (Java Exception)?

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

Помогаем

Unrecognizable

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

Приведем пример кода, в котором возникает исключение.

class ExceptionTest{ 
    // Метод принимает два целых числа
    // и возвращает результат деления
    // первого на второе
    static float divide(int x, int y){
        float result = x / y;
        return result;
    }

    public static void main(String args[]){
        // Эта строка будет выполнена
        System.out.println(divide(4, 2));
        // Эта тоже
        System.out.println(divide(0, 2));
        // Эта выбросит исключение
        System.out.println(divide(4, 0));
    }
}

Если его запустить, получим следующий вывод:

Вибудовуйте якісний і привабливий бренд роботодавця всього за один місяць.

РЕЄСТРУЙТЕСЯ!

Contract agreement

2.0
0.0
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at ExceptionTest.divide(ExceptionTest.java:6)
        at ExceptionTest.main(ExceptionTest.java:16)

Выводятся два результата деления и сообщение об исключении. В этом сообщении указана следующая информация:

  • тип исключения (ArithmeticException);
  • какое именно исключение возникло (деление на ноль);
  • стек выполнения: методы и строки, в которых возникло исключение.

Операторы try, catch, finally, throw, throws: обработка исключений и примеры использования

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

try-catch

Для перехвата исключения используется конструкция trycatch. Код, который нужно проверить на исключение, заключается в блок try, а код, обрабатывающий исключение – в блок catch.

Добавим эти блоки в приведенный выше блок кода и дополним его парой переменных для наглядности.

class ExceptionTest{  
    // Метод принимает два целых числа
    // и возвращает результат деления
    // первого на второе
    static float divide(int x, int y){
        float result = x / y;
        return result;
    }

    public static void main(String args[]){
        int x = 4;
        int y = 2;
        try {
            // Эта строка будет выполнена
            System.out.println(divide(x, y));

            x = 0;
            // Эта тоже
            System.out.println(divide(x, y));

            x = 4;
            y = 0;
            // Эта выбросит исключение
            System.out.println(divide(x, y));
        } catch (ArithmeticException e) {
            System.out.println("Ошибка при делении " + x + " на " + y);
        }
    }
}

Получим более удобочитаемый вывод:

2.0
0.0
Ошибка при делении 4 на 0

finally

Блок finally выполняется после try-catch, независимо от того, возникло ли исключение. Это необязательный блок, но если нет блока catch, то блок finally необходим.

В этом блоке можно, например, закрыть файл, открытый в блоке try, как в приведенном ниже коде.

import java.io.FileWriter;
import java.io.IOException;

public class FinallyTest {
    public static void main(String[] args) {
        FileWriter writer = null;
        try {
            writer = new FileWriter("out.txt");
            writer.write("Writing to the file!");
            System.out.println("Файл записан успешно.");
        } catch (IOException e) {
            System.out.println("Ошибка записи в файл.");
            e.printStackTrace();
        } finally {
            if ( writer != null ){
                try{
                  writer.close();
                } catch (IOException e) {
                  System. out.println("Ошибка закрытия файла.");
                  e.printStackTrace();
                }
            }
        }
    }
}

throw

В некоторых случаях требуется выбросить исключение самостоятельно. Это делается при помощи ключевого слова throw.

В данном примере метод PrintMe выбрасывает исключение, если его аргумент равен null.

import java.util.LinkedList;

public class ThrowTest
{
  public static void main(String[] args) {
        LinkedList<String> fruits = new LinkedList<String>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("orange");
        fruits.add("mango");

        // Печатает список
        ThrowTest.PrintMe(fruits);

        // Выбрасывает исключение
        ThrowTest.PrintMe(null);
  }

    public static void PrintMe(LinkedList<String> fruits){
        if (fruits == null){
            throw new NullPointerException("Аргумент не инициализирован");
        }
        System.out.println(fruits);
    }
}

throws

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

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

public class ThrowsTest{
    public static void readFromFile() throws IOException {
        // Указываем несуществующий файл, чтобы проверить работу исключения
        try (BufferedReader reader = new BufferedReader(new FileReader("out.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line + "n");
            }
        }
    }

    public static void main(String[] args) {
    try {
            readFromFile();
        } catch (IOException ioe) {
            System.out.println("Файл не найден");
        }
    }
}

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

Исключения в Java делятся на две основные категории: встроенные и пользовательские.

Встроенные исключения

Встроенные исключения – это исключения, которые заранее определены в Java.

Когда возникает встроенное исключение, виртуальная машина Java (JVM) создает объект, принадлежащий классу встроенного исключения. Все исключения происходят от класса java.lang.Throwable, но они определены в нескольких пакетах.

Класс Throwable происходит непосредственно об класса Object и является корневым классом дерева классов исключений. От него происходят два подкласса: Error и Exception. Ошибки и исключения, которые встречаются в программах на Java, являются объектами этих классов.

С использованием класса Throwable можно создавать собственные исключения.

Класс Error является надклассом для всех классов ошибок времени выполнения. Он завершает выполнение программы, если происходит ошибка, связанная с системой или ресурсами (JVM).

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

Примеры ошибок: AssertionError, LinkageError, OutOfMmeoryError, StackOverFlowError, VirtualMachineError.

Класс Exception представляет ошибки, вызванные программой или внешними факторами. Это надкласс для все классов исключений.

Для этого класса существует два конструктора:

  • public Exception() (по умолчанию)
  • public Exception(String message) (принимает строковое сообщение как аргумент)

Эти конструкторы наследуются всеми подклассами исключений. Сам по себе класс Exception не предоставляет собственных методов. Он наследует методы класса Throwable.

Встроенные исключения делятся на две группы: проверяемые (checked) и непроверяемые (unchecked).

Проверяемые исключения в Java

Проверяемые исключения проверяются компилятором Java во время компиляции и не являются подклассами RuntimeException (исключения времени выполнения).

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

Проверяемые исключения обрабатываются либо в блоке try-catch, либо в объявлении метода с ключевым словом throws. Если исключение не обработано, происходит ошибка компиляции.

Проверяемыми исключениями являются все исключения, кроме RuntimeException, Error и их подклассов.

Примеры проверяемых исключений: ClassNotFoundException, IOException, SQLException, IllegalAccessException, FileNotFoundException.

Непроверяемые исключения (исключения времени выполнения) в Java

Непроверяемые исключения в Java – это исключения, которые проверяются JVM, а не компилятором Java. Они возникают во время выполнения программы.

Все подклассы RuntimeException называются непроверяемыми исключениями или исключениями времени выполнения в Java.

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

Компилятор Java не проверяет исключения времени выполнения во время компиляции, независимо от того, обрабатывает ли их программа.

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

Примеры непроверяемых исключений: ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, NegativeArraySizeException, NullPointerException.

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

Исключение Описание
ArithmeticException Выбрасывается, когда возникает исключительная арифметическая ситуация.
ArrayIndexOutOfBoundsException Выбрасывается при попытке обратиться к массиву по недействительному индексу.
ArrayStoreException Выбрасывается при попытке сохранить объект несоответствующего типа в массиве объектов.
ClassCastException Выбрасывается, когда код совершает попытку привести тип объекта к подклассу, экземпляром которого он не является.
ClassNotFoundException Выбрасывается, когда приложение совершает попытку загрузить класс по его имени в строковом представлении с использованием метода forName в классе Class.
CloneNotSupportedException Выбрасывается, когда для клонирования объекта определенного класса вызван метод clone, но класс этого объекта не реализует интерфейс Cloneable.
EnumConstantNotPresentException Выбрасывается, когда приложение производит попытку обратиться к константе из перечисления по имени, но тип этого перечисления не содержит константу с указанным именем.
Exception Класс Exception и его подклассы являются подклассами Throwable и указывают на ситуации, которые могут быть перехвачены приложением.
IllegalAccessException Выбрасывается, когда приложение совершает попытку применить рефлексию, чтобы создать экземпляр (отличный от массива), присвоить полю значение или получить значение поля, вызвать метод, но текущий выполняемый метод не имеет доступа к определению указанного класса, поля, метода или конструктора.
IllegalArgumentException Выбрасывается, когда методу передан недопустимый или неприемлемый аргумент.
IllegalMonitorStateException Выбрасывается, когда нить пытается ожидать монитор объекта или отправить оповещение другим нитям, ожидающим монитор объекта, но указанный монитор не принадлежит ей.
IllegalStateException Выбрасывается, когда метод вызван в недопустимое или неприемлемое время.
IllegalThreadStateException Выбрасывается, когда нить находится в неприемлемом состоянии для выполнения запрошенной операции.
IndexOutOfBoundsException Выбрасывается, когда индекс определенного типа (например, для массива, строки или вектора) находится вне допустимого диапазона.
InstantiationException Выбрасывается, когда приложение совершает попытку создать экземпляр класса с использованием метода newInstance класса Class, но создать экземпляр указанного класса невозможно.
InterruptedException Выбрасывается, когда нить находится в состоянии ожидания, сна или занята каким-либо другим образом, но ее работа прервана либо перед выполнением действия, либо после его выполнения.
NegativeArraySizeException Выбрасывается, когда приложение совершает попытку создать массив отрицательного размера.
NoSuchFieldException Выбрасывается, когда в классе отсутствует поле с указанным именем.
NoSuchMethodException Выбрасывается, когда невозможно найти указанный метод.
NullPointerException Выбрасывается, когда приложение совершает попытку использовать значение null, но требуется указать объект.
NumberFormatException Выбрасывается, когда приложение совершает попытку преобразовать строку в один из числовых типов, но строка имеет недопустимый формат.
RuntimeException Это родительский класс для тех исключений, которые могут быть выброшены при нормальной работе виртуальной машины Java.
SecurityException Выбрасывается менеджером безопасности при нарушении безопасности.
StringIndexOutOfBoundsException Выбрасывается методами класса String при попытке использовать отрицательный индекс или индекс, превышающий размер строки.
TypeNotPresentException Выбрасывается, когда приложение совершает попытку доступа к типу с указанием его имени в виде строки, но не удается найти определение типа с указанным именем.
UnsupportedOperationException Выбрасывается, когда запрошенная операция не поддерживается.

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

Пользовательские исключения создаются пользователями или программистами в соответствии с их собственными потребностями. Они создаются путем расширения класса Exception.

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

Чтобы использовать пользовательское исключение, нужно выполнить следующие действия.

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

Пример исключения с конструктором по умолчанию:

class MyException extends Exception{
    // Конструктор по умолчанию
    MyException(){}
}

class Main{
    public static void main(String[] args){
        try{
            MyException e = new MyException();
            throw e;
        }
        catch(MyException ex){
             System.out.println("Перехвачено пользовательское исключение"); 
        }
    }
}

Этот код выведет следующий текст: “Перехвачено пользовательское исключение”.

Пример исключения с параметром в конструкторе:

class MyException extends Exception{
    MyException(String msg){
        super(msg);
    }
}

class Main{
    public static void main(String[] args){
        try{
            MyException e = new MyException("Перехвачено пользовательское исключение с информацией");
            throw e;
        }
        catch(MyException ex){
             System.out.println(ex.getMessage()); 
        }
    }
}

Вывод будет таким:   “Перехвачено пользовательское исключение с информацией”

Заключение

Исключения в Java позволяют указать пути обхода проблем и исправления их последствий. С их помощью можно поместить логику обработки исключительных ситуаций в отдельные блоки кода (catch), оставив основную логику в блоке try, а логику завершающих действий по обработке исключения – в блоке finally. Исключения могут быть обработаны в методах, где они возникают, или переданы далее с помощью ключевых throw и throws.

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

% Throwable

Класс: java.lang.Throwable

Описание

Throwable — базовый класс всех исключений Java. В инструкциях throw и catch можно использовать только
объекты класса Throwable и его подклассов.

Объект-исключение содержит в себе текстовое сообщение, говорящее о причине ошибки, трассировку стека вызовов на момент
создания, а также, возможно, причину (cause) — исключение более низкого уровня, завёрнутое в данное исключение.

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

Все исключения в Java делятся на две большие и неравные группы. Меньшая группа наследует от класса Error и обозначает
серьёзные низкоуровневые ошибки, после которых продолжение выполнения программы обычно бессмысленно. Большая группа
наследует от класса Exception и отвечает за обычные нештатные ситуации, которые могут возникнуть в ходе выполнения
программы.

Теоретически язык Java не запрещает определить свой подкласс класса Throwable, не производный ни от Error, ни от
Exception. Компилятор будет рассматривать такую неведому зверушку как обычное проверяемое исключение (см. ниже), но
на практике так никто не поступает, да и необходимости в этом нет.

Проверяемые и непроверяемые исключения

Классы Error и RuntimeException занимают особое положение в иерархии исключений. Эти классы, а также все производные
от них, являются непроверяемыми исключениями (unchecked exceptions). Все остальные исключения являются проверяемыми
(checked exceptions). На диаграмме классов выше непроверяемые исключения выделены голубым, а проверяемые
— зелёным.

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

void throwsIOException() throws IOException {
	if (MoonPhase.getCurrent() == MoonPhase.FULL) {
		// непроверяемое исключение; можно обработать, но компилятор не заставляет
		throw new IllegalStateException();
	} else {
		// проверяемое исключение
		throw new IOException();
	}
}

void handlesIOException() {
	try {
		throwsIOException();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

В стандартной библиотеке есть одно нарушение этого правила. Статический метод Class.newInstance передаёт во внешний
код любые исключения, в том числе проверяемые, что позволяет обойти проверки времени компиляции:

public class Thrower {
    private Thrower () throws IOException {
        throw new IOException();
    }

    public static void main(String[] args) {
        try {
            Thrower t = Thrower.class.newInstance();
        } catch (IllegalAccessException | InstantiationException e) {
            // Ну хотя бы эти нужно обрабатывать, но уже поздно
        }
    }
}

Здесь main упадёт по IOException, хотя обычно компилятор заставил бы нас объявить его как throws IOException.
Мораль в том, что при использовании рефлексии всегда нужно быть осторожными, потому что она предоставляет внеязыковой
механизм манипуляции классами и методами.

Ошибки (Error)

Исключения, производные от класса Error, являются непроверяемыми и обладают объединяющими свойствами:

  1. Они сигнализируют о серьёзных ошибках низкого уровня, после которых восстановление обычно невозможно.
  2. Многие из них (в частности, OutOfMemoryError, LinkageError и ThreadDeath) могут возникнуть практически в любом
    месте программы, поэтому настраиваться на них заранее обычно бессмысленно. Кроме того, место, где выбрасывается
    исключение, обычно не связано с местом логического возникновения нижележащей проблемы.

Ловить и обрабатывать исключения, производные от Error, обычно не следует. Они выбрасываются затем, чтобы как можно
быстрее дать потоку завершиться аварийно, выполнив при этом все блоки finally при раскрутке стека.

Вот некоторые наиболее распространённые исключения типа Error:

StackOverflowError
: Переполнение стека вызовов. Обычно это указывает на бесконечную рекурсию.

OutOfMemoryError
: Переполнение кучи, причём сборщик мусора уже попытался её почистить и беспомощно развёл руками. Обычно это указывает
на утечки памяти, вызванные хранением ссылок на множество ненужных объектов в корневых переменных.

LinkageError
: Базовый класс для различных ошибок при загрузке классов, необходимых для работы выполняемого кода. Сюда относятся в
том числе NoClassDefFoundError и ExceptionInInitializerError.

NoClassDefFoundError
: JVM не может найти класс, к которому пытается обратиться код. Это может случиться, если код был скомпилирован с
зависимостью от какого-то класса или библиотеки, но запущен при отсутствии этого класса/библиотеки в classpath.

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

ThreadDeath
: В многопоточной программе чужой поток нагло и бесцеремонно завершил работу нашего потока методом Thread.stop. Если
поток завершается по этому исключению, по умолчанию сообщение об ошибке подавляется и не пишется в консоль.

AssertionError
: Нарушено базовое условие, которое в корректно работающей программе должно выполняться всегда. Исключения этого класса
бросает инструкция assert при запуске JVM с параметром -ea (enable assertions), а также библиотека JUnit при провале
тестов.

Как правило, не стоит выбрасывать исключения типа Error инструкцией throw, кроме исключения AssertionError. Его
принято выбрасывать как «невозможное» исключение, чтобы «заткнуть» выбросом исключения пути выполнения, которые заведомо
никогда не будут выполнены, но компилятор об этом не знает. Часто это приходится делать при использовании перечислимых
типов в инструкции switch:

public enum Stoplight { RED, YELLOW, GREEN }
public enum CarState { STOPPED, STOPPING, MOVING }

public class Car {
	public CarState approachIntersection(Intersection intersection) {
		switch (intersection.getStoplight()) {
		case RED:
			stop();
			return CarState.STOPPING;
		case YELLOW:
			if (stopIfPossible()) {
				return CarState.STOPPING;
			} else {
				return CarState.MOVING;
			}
		case GREEN:
			keepMoving();
			return CarState.MOVING;
		default:
			// не может случиться
			throw new AssertionError();
		}
	}
	
	public CarState handleStoplightSwitch(Stoplight stoplight) {
		switch (stoplight) {
		case RED:
			return CarState.STOPPED;
		case YELLOW:
			prepareToMove();
			return CarState.STOPPED;
		case GREEN:
			startMoving();
			return CarState.MOVING;
		default:
			// не может случиться
			throw new AssertionError();
		}
	}
}

В нашем случае у светофора всего три возможных состояния, но компилятор тем не менее требует, чтобы блок switch
обработал невозможную ситуацию default. С помощью throw new AssertionError мы затыкаем компилятор и говорим
сопровождающему код, что эта строка кода заведомо не выполнится.

Ещё один частый use case для AssertionError — блок catch для исключения, невозможного по определению.
Например, стандартные классы URLEncoder и URLDecoder имеют методы, принимающие два параметра: перекодируемую строку
и строку с именем кодировки.

String url = "https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA";
String decodedUrl = URLDecoder.decode(url, "UTF-8");

Этот код просто так не скомпилируется, потому что метод URLDecoder.decode объявлен как
throws UnsupportedEncodingException. Однако кодировка UTF-8 гарантированно поддерживается в любой реализации JVM,
поэтому на самом деле это исключение никогда не выбросится (но компилятор, увы, об этом не знает). Нам придётся
обернуть этот код в идиому «невозможное исключение» (impossible exception):

try {
	String url = "https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA";
	String decodedUrl = URLDecoder.decode(url, "UTF-8");
	// https://ru.wikipedia.org/wiki/Стек
} catch (UnsupportedEncodingException e) {
	// не может случиться
	throw new AssertionError(e);
}

Большинство методов, работающих с кодировками, имеют версии, принимающие вместо строки с именем кодировки объект
класса Charset и не бросающие UnsupportedEncodingException. Им можно передавать константы из класса
StandardCharsets:

List<String> fileContents = Files.readAllLines(
		Paths.get("отчёт.txt"), StandardCharsets.UTF_8);
fileContents.forEach(System.out::println);

К сожалению, некоторые старые классы, в том числе URLEncoder и URLDecoder, так и не были обновлены для поддержки
параметров типа Charset.

Исключения времени выполнения (RuntimeException)

Строго говоря, все исключения возникают во время выполнения, но класс RuntimeException занимает особое положение.
Во-первых, RuntimeException и все производные от него исключения являются непроверяемыми. Во-вторых,
многие из этих исключений сигнализируют об ошибках в программном коде и в корректно написанной программе не должны
возникать вообще. Такие исключения полезно выбрасывать в собственных public-методах в качестве предусловий
(preconditions), краткий смысл которых состоит в том, чтобы сказать вызывающему коду: «Ты виноват, такой ситуации вообще
не должно быть».

Вот некоторые самые важные из них:

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

IllegalArgumentException
: Метод был вызван с недопустимым значением параметра. Например, один из конструкторов стандартного класса Color,
принимающий три целых числа RGB, выбрасывает это исключение, если переданные числа не лежат в диапазоне 0–255.

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

IndexOutOfBoundsException
: Попытка обратиться к упорядоченной последовательности элементов (массиву, строке или списку) по индексу, лежащему
вне допустимых значений. Часто происходит при ошибке на единицу, когда в качестве индекса используется length или
size.

NoSuchElementException
: Выбрасывается итератором при попытке прочитать элемент за концом последовательности (когда hasNext() == false). В
корректной реализации итератора это исключение возможно только при ручной работе с итератором и невозможно при
использовании цикла for-each.

UnsupportedOperationException
: Вызываемая операция в принципе запрещена для этого объекта. Например, неизменяемые коллекции выбрасывают это
исключение при попытке изменить их методами set, add или remove.

ArithmeticException
: Вызвана недопустимая арифметическая операция, например, деление на ноль. Операции над числами с плавающей точкой не
выбрасывают это исключение, вместо этого при недопустимой операции они возвращают значение NaN (а при делении
ненулевого числа на ноль — бесконечность).

ClassCastException
: Попытка привести объект к несовместимому типу, например, (String) new Object().

Все эти исключения объединяет то, что в корректно написанной программе они не должны выбрасываться. Если одно из этих
исключений ловится в программе, это знак неверной логики кода. Часто отлов такого исключения можно заменить проверкой;
например, вместо отлова ClassCastException использовать оператор instanceof, вместо IndexOutOfBoundsException
— проверку диапазона (index >= 0 && index < size()), а вместо NoSuchElementException — проверку
Iterator.hasNext().

Прочие исключения (Exception)

Исключения, производные от Exception, но не RuntimeException, являются проверяемыми. Их очень много, и сторонние
библиотеки часто добавляют свои собственные классы исключений. Вот лишь несколько примеров:

ReflectiveOperationException
: Базовый класс для исключений, возникающих при работе с механизмом рефлексии. Сюда относятся IllegalAccessException
(попытка доступиться извне к членам класса с доступом private, protected или package-private), NoSuchMethodException
(метод не найден) и InvocationTargetException (оборачивает исключение, выброшенное вызываемым через рефлексию
методом). Отдельно стоит выделить…

ClassNotFoundException
: Не путать с NoClassDefFoundError. Выбрасывается методом Class.forName, если класс с таким именем не найден. Это
исключение, в отличие от NoClassDefFoundError, предназначено для того, чтобы его перехватывали и обрабатывали.

CloneNotSupportedException
: По умолчанию выбрасывается protected-методом Object.clone, если объект не реализует интерфейс Cloneable. По
каким-то непонятным причинам конченые укурки, проектировавшие Java 1.0, сделали это исключение проверяемым, и при
реализации Cloneable-классов это исключение приходится подавлять.

SQLException
: Базовый класс для ошибок при работе с базами данных через JDBC API.

IOException
: Базовый класс для исключений при операциях ввода-вывода, к которым относятся операции, в том числе, с файловой
системой и сетью. У этого класса очень много подклассов, обозначающих конкретные ситуации; например,
ConnectException бросается при неудачной попытке соединения с сервером.

FileSystemException
: Подкласс IOException, являющийся базовым классом для исключений при операциях с файловой системой.

AccessDeniedException
: Попытка обратиться к файлу, на доступ к которому у пользователя нет прав — например, попытка открыть
защищённый системный файл для записи.

NoSuchFileException
: Попытка обратиться к несуществующему файлу.

Класс NoSuchFileException появился в Java 7 и является частью нового файлового API (классы Path и Files). В
старых API, спроектированных для Java 6 и ниже, можно встретить более старое исключение FileNotFoundException,
присутствовавшее ещё в Java 1.0. К сожалению, это исключение не позволяет различить ситуации «файл не найден» и «доступ
запрещён» и выбрасывается старыми API в обоих этих случаях.

Использование проверяемых и непроверяемых исключений

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

Выбрасывайте проверяемые исключения только при одновременном выполнении трёх условий:

  1. Вызывающий код не может гарантированно избежать ошибочной ситуации, то есть она находится вне его полного контроля.
  2. Ошибочная ситуация является «стандартной», то есть в любом случае автору вызывающего кода нужно думать о том, что
    произойдёт при возникновении ошибки. Например, при попытке открыть файл может оказаться, что файл недоступен.
  3. Вызывающий код может осмысленно обработать ошибку или даже восстановиться после неё.

Хорошими примерами проверяемых исключений являются исключения при работе с файловой системой, сетью, базами данных,
окнами, другими процессами в системе и т.д. Все эти сущности объединяет то, что это внешние ресурсы, корректную работу
которых вызывающий код не может полностью гарантировать. Плохой пример проверяемого исключения — исключение
CloneNotSupportedException, которое может возникнуть только при логической ошибке в использовании метода clone.
Если бы класс CloneNotSupportedException был написан в наши дни, скорее всего, это исключение было бы непроверяемым.

Если хотя бы одно из этих трёх условий не выполняется, используйте непроверяемые исключения. Вот примеры ошибок, для
которых подходят непроверяемые исключения:

  • Низкоуровневые ошибки самой JVM и загруженных классов (Error).
  • Ошибки в логике программы, необнаружимые на этапе компиляции (RuntimeException).
  • Ошибки, при которых продолжение выполнения кода не имеет смысла. Например, в серверных приложениях это могут быть
    ошибки конфигурации сервера, при которых приложение вообще не может запуститься, или ошибки доступа к основной базе
    данных, с которой работает серверное приложение (здесь само приложение всё равно не сможет восстановиться). Как правило,
    такие исключения тоже наследуют от RuntimeException.

Создание исключения

Объекты исключений, как правило, создаются прямо в инструкции throw:

throw new SomeException(параметры);

По соглашению у большинства классов исключений есть четыре конструктора, позволяющие задать исключению сообщение и/или
причину — более низкоуровневое исключение.

SomeException()

SomeException(String message)

SomeException(Throwable cause)

SomeException(String message, Throwable cause)

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

try {
	readConfigFile("server-config.xml");
} catch (XMLStreamException e) {
	throw new ServerStartupException("Invalid server configuration format", e);
} catch (IOException e) {
	throw new ServerStartupException("Cannot access server configuration", e);
}

У некоторых очень старых классов исключений, написанных до выхода Java 1.4, может не быть конструкторов с параметром
cause. Для них можно установить причину после создания объекта с помощью метода initCause:

throw new OldException("Message").initCause(e);

Получение информации об исключении

Все исключения поддерживают три базовых операции:

String getMessage()
: Возвращает короткое, в одно-два предложения, сообщение об ошибке, переданное в объект исключения при его создании.

Throwable getCause()
: Возвращает исключение, послужившее причиной данного исключения, или null, если таковое не было задано. У причины,
в свою очередь, тоже может быть причина; с помощью последовательных вызовов getCause можно восстановить причинную
цепь исключений (causal chain).

void printStackTrace()
void printStackTrace(PrintStream s)
void printStackTrace(PrintWriter s)
: Выводит трассировку стека (stack trace) в указанный байтовый или символьный поток (по умолчанию — в
System.err). Варианты с PrintStream и PrintWriter бывают полезны, чтобы записать трассировку стека в файл или
сетевой поток, либо получить её в виде строки с помощью StringWriter.

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

По умолчанию для всех исключений, кроме ThreadDeath, при завершении потока по необработанному исключению трассировка
стека записывается в System.err с помощью printStackTrace. Это относится и к главному потоку при аварийном
завершении метода main.

Как пример, вот такая неправильная программа

public class ExceptionChain {
	private static class BadInitializer {
		private static final char CONSTANT = "Hello".charAt(5);
	}
	
	public static void main(String[] args) {
		System.out.println(BadInitializer.CONSTANT);
	}
}

при выполнении выдаст:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at ExceptionChain.main(ExceptionChain.java:11)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 5
	at java.lang.String.charAt(String.java:658)
	at ExceptionChain$BadInitializer.<clinit>(ExceptionChain.java:7)
	... 1 more

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибки врачей при постановке диагноза
  • Ошибки врачей при лечении коронавируса