- 예외 처리목적
- try ~ catch ~ finally 구문을 이용한 예외 처리
- throws 구문을 이용한 예외 처리
- 사용자 정의 예외 처리
1. 예외 처리란?
- 예상치 못한, 치명적인 상황이 발생할 때 시스템을 비정상적으로 종료되는 것을 막는 행위 (Exception)
int result = 10 / 0;
- 이렇게 계산이 되지 않는 상황에 예외 처리를 실시한다.
2. 예외 클래스
- Checked Exception
- 컴파일 시에 예외 처리를 해 주었는지 체크하는 Exception (빨간 밑줄 - 쉽게 확인할 수 있음)
- IOException
- Unchecked Exception
- 프로그램 실행 중에 발생하는 Exception (코드 작성때 유의해야 한다. - 쉽게 발견할 수 없음)
- ArithmaticException
2-1 자주 발생하는 Exception 종류
Exception 종류 | 설명 |
*ArithmeticException | 산술 연산 중, 0으로 나누었을 때 발생 |
*NumberFormatException | 숫자로 변경될 수 없는 문자열을 숫자로 변경하려고 시도하는 경우 발생 |
*NullPointerException | 참조 데이터형 변수의 값이 null인데 객체에 접근하려고 하는 경우 발생 ex) Student를 null로 설정했는데 이를 객체로 사용할 경우 |
*ArrayIndexOutOfBoundsException | 배열의 범위를 벗어난 인덱스에 접근하려고 할 때 발생 ex) 크기가 4인 배열에 5번째 요소를 접근할 경우 |
*ClassCastException | 체의 형 변환 시, 잘못된 클래스로 변환하려고 할 때 발생 |
3. try ~ catch ~ finally
기본적인 try ~ catch 형태
try {
//Exception이 발생할 가능성이 있는 구문
} catch(Exception_클래스_타입 변수명) {
//Exception이 발생했을 경우 수행해야 하는 문장
}
- 예제
try {
int result = num1 / num2;
} catch(ArithmeticException e) {
System.out.println("num2는 0이 될 수 없습니다.");
}
- num2가 0이 될 가능성이 있으므로 try 구문에 넣어준다.
- 이 경우 발생하는 Exception은 ArithmeticException이므로 클래스 타입 변수명은 다음과 같이 넣어준다.
try
- Exception이 발생할 가능성이 있는 코드를 try블록으로 감싼다.
- try 블록 안에 있는 문장들은 Exception이 발생하지 않는 한, 모두 정상 수행된다.
- Exception이 발생하면, 즉시 발생한 Exception 객체를 catch 블록으로 전달한다.
catch
- Exception 객체를 받아서, 예외 상황이 발생했을 때 수행할 일들을 작성해 준다.
- 여러 가지 Exception 클래스 타입들 중, 발생 가능성이 있는 클래스 객체를 선언해준다.
4. 예제
- Student 클래스
package chapter12;
public class Student {
private String classname;
private String name;
Student(String classname, String name){
this.classname = classname;
this.name = name;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- ExceptionBasicEx Class
package chapter12;
public class {
public static void main(String[] args) {
Student[] students = new Student[5];
students[0] = new Student("STU001", "홍길동");
students[1] = new Student("STU002", "홍길순");
for(int inx = 0; inx < students.length; inx++) {
try {
System.out.println(students[inx].getName());
} catch (NullPointerException e) {
System.out.println("값이 null입니다.");
}
}
}
}
//출력 결과
홍길동
홍길순
값이 null입니다.
값이 null입니다.
값이 null입니다.
4-1 예제
- 수강생 4명의 이름을 출력하려고 한다.
- 이름정보는 배열에 담아 관리, 반복문을 이용하여 각 배열 요소에 접근한다.
- 그런데 실수로 인덱스 0~3번이 아닌 14번까지 반복문을 작성하게 되었다.
- 이때 발생하는 Exception과 처리를 위해서 어떻게 하는지 작성해보자.
package chapter12;
public class PrintNameTest {
public static void main(String[] args) {
String[] names = {"전우치","홍길동","홍길순","임꺽정"};
for(int i = 1; i<=names.length; i++) {
try {
System.out.println(names[i]);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("에러!! 잘못된 경로");
}
}
}
}
//출력 결과
홍길동
홍길순
임꺽정
에러!! 잘못된 경로
5. 여러 형태의 Exception이 발생하면?
try {
//Exception이 발생할 가능성이 있는 구문
} catch(Exception_클래스_타입 변수명) {
//Exception이 발생했을 경우 수행해야 하는 문장
} catch(Exception_클래스_타입2 변수명){
//Exception2가 발생했을 경우 수행해야 하는 문장
}
- 위에서부터 내려오므로 (else if 개념) 위에서 예외상황이 걸리면 아래부분을 실행하지 않고 넘어가게 된다.
- 하위 클래스의 예외부터 상위 클래스의 예외 순서로 작성
- Exception이 발생하면 위에서부터 차례대로 검사하면서 알맞은 catch 블록을 찾아 수행
- 제일 마지막에는 최상위 Exception 클래스를 작성하여 모든 예외 사항을 처리할 수 있음.
6. 반드시 수행되는 Finally
- try 블록 안 코드의 Exception 발생 유무와 상관 없이 반드시 수행해야 하는 문장
- catch 블록이 모두 끝난 후 finally 블록을 작성
try {
//Exception이 발생할 가능성이 있는 구문
} catch(Exception_클래스_타입 변수명) {
//Exception이 발생했을 경우 수행해야 하는 문장
} finally{
//반드시 수행해야 하는 문장
}
- 예외가 발생하건 안하건 꼭 수행되야 한다.
6-1. 예제
- 100을 -3부터 3까지 순차적으로 나누어 결과를 출력한다.
- 나누기 연산은 Exception이 발생할 여지가 있으므로 예외 처리를 한다.
- 연선을 한 번 수행할 때마다 구분자로 "--------" 문자열이 무조건 출력되도록 하자.
package chapter12;
public class DivideTest {
public static void main(String[] args) {
for(int i = -3; i<=3; i++) {
try {
int result = 100/i;
System.out.println("100 /" + i + " = " + result);
} catch(ArithmeticException e) {
System.out.println("잘몬된 연산 발생!!");
} finally {
System.out.println("----------------");
}
}
}
}
//출력 결과
100 /-3 = -33
----------------
100 /-2 = -50
----------------
100 /-1 = -100
----------------
잘몬된 연산 발생!!
----------------
100 /1 = 100
----------------
100 /2 = 50
----------------
100 /3 = 33
----------------
6-2. 실습
- arrayOne, arrayTwo라는 2개의 배열이 있다.
- 두 개의 배열에서 같은 인덱스 번호의 값을 추출하고, 첫 번째 배열의 값을 두 번째 배열의 값으로 나누기 연산한다.
- 예외 상황이 발생하면 비정상적으로 종료되지 않도록 하고 작동하게 해보자.
package chapter12;
public class ArrayDivideTest {
public static void main(String[] args) {
int[] arrayOne = {10,20,13,25};
int[] arrayTwo = {2,5,0,3};
for(int i = 0; i< arrayOne.length; i++) {
try {
System.out.println(arrayOne[i] + " / " + arrayTwo[i] + " = " +
(arrayOne[i] / arrayTwo[i]));
} catch (ArithmeticException e) {
System.out.println("나누기 연산 시 에러가 발생하였습니다. ");
}
}
}
}
//출력 결과
10 / 2 = 5
20 / 5 = 4
나누기 연산 시 에러가 발생하였습니다.
25 / 3 = 8
'Web Development > Java' 카테고리의 다른 글
예외 처리 - 사용자 정의 예외 (0) | 2022.10.11 |
---|---|
예외 처리 - throws 구문 (0) | 2022.10.11 |
HashMap (0) | 2022.10.08 |
List Collection (0) | 2022.10.08 |