The second in a series that I'm not good at forever.
Even if the program compiles successfully, an error may occur when it is executed. In Java, errors that occur at runtime are called ** exceptions **. The occurrence of an exception is called ** an exception is thrown **.
When an exception is thrown, if the program does not describe any processing for the exception, the program will be forcibly terminated **.
In the following Sample.java, an exception will be thrown because it accesses outside the elements of the prepared array.
1¥Sample.java
public class Sample {
public static void main(String[] args) {
int[] num = {10, 20, 30};
for (int i=0; i<4; i++) {
System.out.print("num :" + num[i]);
System.out.println(" : " + (i+1) + "Second loop");
}
System.out.println("--end--");
}
}
Execution result
num : 10 :1st loop
num : 20 :Second loop
num : 30 :3rd loop
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at Sample.main(Sample.java:5)
In this Sample.java, an array is prepared and each element is output using the for statement. However, the Java runtime environment throws an exception because the fourth loop is accessing outside the elements of the array. Looking at the execution result, you can see that the program has ended halfway because the output of "--end--" on the 8th line is not output. Applications that continue to run must be prevented from crashing due to potential run-time errors. Therefore, Java uses a mechanism called ** exception handling **. Exception handling describes what to do if an exception occurs, which allows the program to continue execution without being killed.
Java exception classes are divided into two types: ** checked exceptions ** and ** unchecked exceptions . The checked exception is an exception that occurs due to an environment other than the Java execution environment such as DB. On the other hand, unchecked exceptions are exceptions caused by a running program ( runtime exception **) and exceptions that cannot be recovered by program exception handling such as out of memory. The characteristic of checked exceptions is that ** exception handling is mandatory **. Unchecked exceptions, on the other hand, mean that exception handling is ** optional rather than mandatory **. In addition, exception classes fall into three categories:
--Error class and its subclasses (unchecked exceptions) --RuntimeException class and its subclasses (unchecked exceptions) --Subclass of Exception other than RuntimeException class (checked exception)
The ** Throwable ** class is the root class of the exception class. The ** Error ** and ** Exception ** classes are provided as subclasses of the Throwable class. The Error class represents a fatal error that occurs in the Java runtime environment such as insufficient memory, and it is difficult for the application to handle this exception, so the handling for exceptions in this class and subclass is ** optional **. It has become. The Exception class expresses an error that occurs in the application, such as "A program tried to write to a file but the file did not exist" or "Accessed outside the elements of the array". However, in order to compile successfully, there are two cases, one is that the processing for these exceptions must be described, and the other is that it is not necessary to describe it. This decision is made not by what is being handled, but by ** what exception classes may occur as a result of processing **. ** Optional ** if it is a RuntimeException class and its subclasses, ** Required ** if it is a subclass of an Exception other than the RuntimeException class.
The following are some of the exception classes provided by Java, so let's focus on the exception class name and whether it is included in an unchecked exception or a checked exception. In addition, the exception classes written in ** bold ** have a high frequency of questions, so it is a good idea to check when the exception occurs.
name of the class | Description |
---|---|
AssertionError | Occurs when false is returned in a boolean expression while using an assert statement |
OutOfMemoryError | Occurs when memory is insufficient and no more usable memory can be secured even if the garbage collector is running |
StackOverflowError | Occurs when the application recurses too many times |
NoClassDefFoundError | Occurs when the class file you are trying to read cannot be found |
name of the class | Description |
---|---|
ArrayIndexOutOfBoundsException | Occurs when trying to access an element with an invalid index |
ClassCastException | Occurs when you cast the wrong reference variable |
IllegalArgumentException | Occurs when an invalid method argument is used |
ArithmeticException | Occurs when an integer is divided by zero |
NullPointerException | Occurs when a method is called for a reference variable to which null is assigned |
NumberFormatException | Occurs when trying to convert a string that does not represent an integer to an integer |
name of the class | Description |
---|---|
IOException | Occurs when there is some kind of input / output failure |
FileNotFoundException | Occurs when the target file does not exist in file input / output |
ClassNotFoundException | Occurs when trying to load a class using a method with a string representing the class name as an argument, but the class file is not found |
Java provides many exception classes, but programmers can also define their own exception classes. Generally, it is defined as a public class that inherits the Exception class.
Sample.java
[Modifier]class class name extends Exception{ }
Example) public class MyException extends Exception{ }
By inheriting the Exception class, you will inherit the methods provided by the Exception class and its superclass, the Throwable class. The Throwable class provides methods such as extracting error messages from exceptions and tracking errors to identify where they occur (error tracing).
name of the class | Description |
---|---|
void printStackTrace() | Output an error trace that tracks errors and identifies where they occur |
String getMessage() | Get the error message |
There are two ways to handle exceptions in Java.
--try-catch-finally block exception handling --Exception handling by throws keyword
In this section we will look at exception handling using the ** try-catch-finally ** block. The try-catch-finally block consists of a try block, a catch block, and a finally block, and the processing is described in each block as follows.
Sample.java
void method() {
try {
Processing that is likely to cause an exception;
} catch (Exception class name Variable name) {
What to do when an exception occurs;
} finally {
The process you definitely want to execute;
}
}
The role of each block is as follows.
--try block: Enclose the place where an exception is likely to occur with a try block --catch block: Define the processing when an exception occurs in the catch block --finally block: Define the process you want to execute in the finally block regardless of whether an exception occurs or not.
It is the role of the try-catch-finally block to receive the exception object thrown from the Java runtime environment. The catch block is written with the following syntax.
Sample.java
catch (Exception class name Variable name) { }
(Example) catch(ArrayIndexOutOfBoundsException e) { …… }
In 1 \ Sample.java, an exception called ArrayIndexOutOfBoundsException is thrown, so define it as in the above example. It is not necessary to describe all the blocks of try-catch-finally. The following combinations are possible.
Now let's use the try-catch block to add exception handling to the previous sample.
2¥Sample.java
public class Main {
public static void main(String[] args) {
int[] num = {10, 20, 30};
for (int i=0; i<4; i++) {
try {
System.out.print("num :" + num[i]);
System.out.println(" : " + (i+1) + "Second loop");
} catch (ArrayIndexOutOfBoundsException e) { //8th line
System.out.println("Exception occured");
}
}
System.out.println("--end--"); //12th line
}
}
Execution result
num : 10 :1st loop
num : 20 :Second loop
num : 30 :3rd loop
Exception occured
--end--
Similar to 1 \ Sample.java, the exception is raised in the 4th loop, but the exception object is caught in the catch block on the 8th line. As a result, you can see that the program is not forcibly terminated and the processing on the 12th line is being executed continuously.
Use the `finally block if there is something you want to do, whether or not an exception occurs. For example, releasing resources (such as database close processing and file close processing). ``
You can define multiple catch blocks to handle multiple exception classes that can occur within a try block.
Sample.java
} catch (Exception class name Variable name) {
processing;
} catch (Exception class name Variable name) { }
However, if there is an inheritance relationship between the exception classes specified in the catch block, ** describe from the subclass side **. Writing from a superclass will result in a compile error.
✴︎ throws In addition to exception handling by the try-catch-finally block, exception handling by the ** throws ** keyword is possible. In this method, when defining a method that may raise an exception, specify "** throws exception class name **". This will cause the exception object to be * forwarded to the method caller ** if an object of the exception class specified in throws occurs in the method. The syntax is as follows:
Sample.java
[Modifier]Return type method name(Argument list)throws exception class name{ }
For the exception class name, specify the exception class name that you want to forward to the method caller for exceptions that may occur within this method. If there are multiple exception classes to specify, list the exception class names separated by "," (comma).
3¥Sample.java
class Test {
void loop() throws ArrayIndexOutOfBoundsException {
int[] num = {10, 20, 30};
for (int i=0; i<4; i++) {
System.out.println("num : " + num[i]);
}
}
}
public class Sample {
public static void main(String[] args) {
try {
Test t = new Test();
t.loop();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception occured");
}
System.out.println("--end--");
}
}
Execution result
num : 10
num : 20
num : 30
Exception occured
--end--
The loop () method of the Test class is explicitly defined to throw an ArrayIndexOutOfBoundsException exception. Looking at the execution result, you can see that the exception that occurred on the loop () method side is forwarded to the main () method side, and the catch block of the main () method receives it.
Even if you delete the " throws ArrayIndexOutOfBoundsException
"part, an ArrayIndexOutOfBoundsException exception will be thrown and the execution result will be the same. This is because the exception class (ArrayIndexOutOfBoundsException) that occurred is an unchecked exception, and exception handling is not mandatory, so it can be compiled and executed without problems.
✴︎ throw Exceptions can be thrown not only by the Java runtime environment, but also explicitly in your program using the ** throw ** keyword. It's very similar to the throws keyword above, but be careful not to get confused. You can use the throw keyword to throw an exception object that instantiates an exception class provided by Java or your own exception class anywhere.
Sample.java
throw exception object;
(Example 1) throw new IOException();
(Example 2) IOException e= new IOException();
throw e;
Below, the MyException class is defined as a unique exception class. And in the checkAge () method of the Sample class, if a value less than 0 is passed as an argument, a MyException object is created and explicitly thrown with the throw keyword.
4¥Sample.java
class MyException extends Exception { //Proprietary exception class
private int age;
public void setAge(int age) { this.age = age; }
public int getAge() { return this.age; }
}
public class Sample {
public static void main(String[] args) {
try {
int age = -10;
checkAge(age); //11th line
} catch (MyException e) { //12th line
System.out.println("Illegal value. age: " + e.getAge()); //13th line
}
}
public static void checkAge(int age) throws MyException { //16th line
if (age>=0) {
System.out.println("OK");
} else { //Line 19
MyException e = new MyException(); //20th line
e.setAge(age);
throw e; //Line 22
}
}
}
Execution result
Illegal value. age: -10
Line 11 calls the checkAge () method defined on line 16. The 17th line evaluates whether the value of the age variable received as an argument is 0 or more. If it is not 0 or more, control moves to the 19th line or less. Then, the original exception class prepared in the first line is instantiated in the 20th line and explicitly thrown in the 22nd line. The thrown exception is caught on line 12 of the caller of the checkAge () method and the message is printed on line 13.
The precautions for overriding are coming again.
Recommended Posts