JavaRush /Java Blog /Random EN /Exceptions in Java
Roman
Level 33

Exceptions in Java

Published in the Random EN group
When I came across the topic “Exceptions,” many questions arose to which I had to look for answers in various corners of the Internet in order to understand in detail how it all works. As a result, I have compiled my own explanation, which may be more understandable for beginners who have just encountered this phenomenon. Exceptions in Java - 1In computers, an interrupt is an incoming signal to the processor that an event is occurring that requires an immediate response. An interrupt signal requires the processor to pause a running program so that it can be continued a little later, that is, the computer must remember all the information associated with the execution of the program. Such interruptions are temporary, if not fatal. Such interruptions can be caused either by program code or by some hardware functionality (for example, simply pressing keys on the keyboard; timers, for example, to automatically turn off the computer). The number of Interrupts is limited to a certain number, built into the production of a particular processor, that is, special communication “channels” are allocated for this, allowing you to access the processor bypassing all other processes. Interrupts are also automatically generated when an error occurs in the executing program code (for example, if a division by zero occurs). Such interruptions are traditionally called traps or exceptions . In such cases, it is customary to say: “Exception was thrown,” that is, an Exception was triggered or an Exception was thrown (thrown), that is, a request for an Interruptwith the question “what to do?” sent to the processor. At this moment, the processor stops working, remembering the point at which it stopped, or rather the cluster of the next cell, the information from which must be executed. The entire chain of executed and NOT executed instructions is remembered. After which, the processor reads instructions from memory for action in the event of such an error. In accordance with this instruction, it can enter new values ​​into certain clusters, add some chains of actions or a new cycle (for example, a return or looping cycle), etc., that is, depending on the error, previously laid down instructions are executed. The computer system itself has many automatic Interrupts built into it, which are triggered after a certain amount of time, for example, to control processes running on the computer or run set alarms, collect incoming external signals, and various data converters. It is worth remembering that a large number of Interrupts, for a number of reasons, can completely “hang” the system. An error in the program code will automatically cause an interruption in the processor, which it will try to process in accordance with the laid down instructions. But not all interrupts are designed to handle them, or it may produce a procedure that does not suit us, for example, it will simply crash the application. Therefore, in programming, it is possible to organize your own interrupt for a certain section of code in which the programmer potentially sees the possibility of an error. In this case, the error will be processed within the program and will not contact the processor for processing instructions. The definition of such blocks is organized by creating an “Exception” Object . This object is automatically created in the block try-catch. The block >tryis checked for the presence of an error and, if there is one, the program goes to the block catch, where actions are taken to prevent or level the error. For example, if we enter Numbers from the keyboard , which must subsequently be added and subtracted, then entering Letters from the keyboard will make it impossible to add them with Numbers (let’s denote the sum of these two variables by the letter S). Therefore, as a team, trywe must check whether number A, containing Numbers, can be added to number B, containing Letters (that is, S = A + B), and if this is not possible, and it is impossible, then certain measures must be taken so that Errors It did NOT happen and a new Interrupt with the question “what to do?” did not fly to the processor. If there is no Exception in the program, its execution will be interrupted by the processor. If there is an Exception, when it is “caught” by the command try, control passes to the command catch, which can set an alternative solution, for example, we will not add these two numbers, but set S = A.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 } catch (Exception igogo1) {
   S = a;
 }
 return S;
/* string “int r = 1;” is not executed because an error occurred and the program redirects work directly to the exception handler (catch block*/ Thus, the presence of Exceptions is an opportunity to solve the problem within the program without throwing it at the processor level. The “Exception” object, which is automatically created in the block trywhen an error is detected, contains the value of the error type. Let's call it “OurException” - for our specific case with a description of our specific error. The creators of the Java language created in advance a certain list of typical errors and typical options for correcting them, that is, in java there is a certain library of Exceptions , which we can turn to to handle an error that has occurred, so as not to write the processing code ourselves and therefore OurException is most likely already someone has been described, so we just need to know the name of which of these exceptions to insert into our program to handle the code where a failure could potentially occur. If we make a mistake and select an incorrect Exception from the library , then the handler will not “catch” it, the error will not find a solution within the program and the request will be sent to the processor. But there is a way for the lazy. If we do not know the name of the exception we need from the library, then we can take the general one with the name “ Exception ”, as in the example described above. This Exception is capable of handling any type of error, but it is not capable of providing specific information about the incident that we could log. The library of previously written Exceptions consists of checked and unchecked Exceptions . Checkable ones are those that can be corrected without interrupting the work of the program, that is, if we try to open a file in a folder in which it does not exist, the system will let us know about it, we can drop the file into the desired folder and continue the program. That is, in fact, a request for Interrupt was sent to the processor , but without the question: “look for what to do about this problem?!?!” We sent an Interrupt, which we ourselves detected, with a ready-made instruction, which the processor processed and continued executing the program. Unchecked are those errors that cannot be corrected and the program will be closed before completion, that is, an Interrupt request will be sent to the processor, which in any case will interrupt the execution of the program. The only point in writing such exceptions in the program is to let the user understand what happened, since, having caught this interruption, we can display an information message on the screen due to which the program has crashed. The second reason to catch such interruptions is the ability to record them in the logs for subsequent analysis (you were hacked, but at least you know where). A consequence of the presence of such libraries is the need to remember to include them. (A list of checked and unchecked Exceptions with libraries can be found, for example, here ) If we don’t know exactly which library to include or there are several error options, then we can catchlist the required Exceptions in several. The system itself will select the correct handler if it is in the list. Instead of a specific Exception, you can write a general “ Exception ” that can handle any type of Exception if it was not processed in previous blocks.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 }
catch(NullPointerException blabla2) {
   System.out.println("Exception handling code for the NullPointerException.");
 }
catch (ArithmeticException ex1) {
   S = a;
 }
catch(Exception uups1) {
   System.out.println("Exception occured");
 }
 return S;
If there is a block, tryan Exception is created automatically. If we need to force an Exception at some point in time , then the command is used throw. That is, we independently create an object new throw... after which, the program stops its work, sends an Interrupt request to the processor and is transferred to the program section catch, from where it tries to get instructions for further actions. By manually creating an Exception , we can specify its specific type from the library:

throw new ArithmeticException("Access denied - You must be at least 18 years old.");
then the handler will search for a block catchwith this particular Exception - search throughout the program, on all sides catch. After the throwException handling command, all remaining program code will NOT be executed, except for that which is in the block catch. If the handler is not found in the program, the processor is asked the question: “decide for yourself what to do” and it interrupts the program. The call new throw... can be made both inside >tryand outside the block (anywhere in the program)
try {
   /* функция or действие, в котором есть сомнения. То есть: «попробуй выполнить это, а если не получится, а, если не получится, запускай режим исключения» */
   throw new CallForException(); /* Назначаем исключение, которое будет работать в случае наличия ошибки в функции, описанной выше. Здесь исключение «CallForException» - берется из библиотеки существующих исключений */
} catch (CallForException ee1) {
   /* Корректируем ошибку, чтобы программа не «отвалилась» or выводим сообщение об ошибке or что-то ещё */
} finally {
   /* этот блок работает всегда независимо от того была ошибка or нет. А если была, то сработало ли решение в catch or нет */
   /* часто используется для подчистки хвостов, например, для закрытия запущенного file or базы данных */
   /* в ряде случаев блок catch вообще может быть опущен и оставлен только блок finally и наоборот finally может быть опущен и оставлен только catch */
   /* Не допускается использование этого блока в ряде случаев, например, когда функция System.exit() запущена or другие системные Исключения, типа «отключение электроэнергии» и т.п. */
}

Notification of Exceptions

Methods previously written by someone may include throwing Exceptions. Just to be on the safe side, the programmer who wrote the code warned subsequent programmers that an error might occur in the method he wrote. So, for example, the file creation method described below stipulates that when creating a file an error may occur (there is no file at the given path), which means that an error handler will be needed:
public void createFile(String path, String text) throws IOException {
    FileWriter writer = new FileWriter(path, true);
    writer.write(text);
    writer.close();
}
But at the same time, there is no handler itself, which means that now we will not be able to simply call the written method in our program in normal mode. Now we must write an error handler and call this method in the block try:
String filePath = "hello.txt";
String text = "Hello World";

try {
    createFile(filePath, text);
} catch (IOException ex) {
    System.err.println("Error creating file: " + ex);
}

Native exceptions

It is possible to write your own exceptions to handle certain errors if the existing libraries are not enough for us. To do this, we simply create a class that inherits from the Exception class
public class StudentNotFoundException extends Exception {

    public StudentNotFoundException (String message) {
        super(message);
    }
}
There are two rules to keep in mind when creating your own exceptions:
  1. Our class name must end with "Exception"
  2. The class must contain a constructor with a string variable describing the details of the Exception problem. In the constructor, the super constructor is called and a message is passed.
An example of using the generated exception:
public class StudentManager {
    public Student find(String studentID) throws StudentNotFoundException {
        if (studentID.equals("123456")) {
            return new Student();
        } else {
            throw new StudentNotFoundException(
                "Could not find student with ID " + studentID);
        }
    }
}
We catch this Exception with the code:
public class StudentTest {
    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
         try {
            Student student = manager.find("0000001");
        } catch (StudentNotFoundException ex) {
            System.err.print(ex);
        }
    }
}
The result of executing the program will be: StudentNotFoundException: Could not find student with ID 0000001

Why do you need to write Exceptions?

In 1996, the Ariane 5 rocket crashed due to an incorrect conversion of a float variable to an integer variable. There were no exceptions or handlers for this situation. If while downloading a file there is a loss of connection to the Internet, then the presence of an Exception will allow you to continue downloading after the connection is restored. If there is no Exception, the download will have to start again.

References:

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION