3.0
-1.0
2.0
java.lang.RuntimeException: num2는 0이 될 수 없습니다.
at java_project/day06.Exception02.calc(Exception02.java:40)
at java_project/day06.Exception02.main(Exception02.java:14)
num2는 0이 될 수 없습니다.
-1.0
예외 처리는 코드의 안정성과 신뢰성을 확보하기 위한 필수 요소
🔷 RuntimeException : 실행 예외 클래스
- 대표적인 RuntimeException의 하위 클래스에는 다음과 같은 것들이 있다.
👉🏻 NullPointerException: null 객체에 접근
👉🏻 ArrayIndexOutOfBoundsException: 배열의 유효 범위를 초과
👉🏻 IllegalArgumentException: 메서드에 잘못된 파라미터를 전달
public class RuntimeExceptionExample {
public static void main(String[] args) {
String str = null;
// NullPointerException 발생
System.out.println(str.length());
}
}
🔷 Exception : 예외. 개발자가 코드 구현시 발생할 수 있는 에러를 예외
- 예외처리 : 예외를 개발자가 처리하는 구문
- 예외가 발생하면 예외 발생 시점부터 코드는 중지 => 예외문구 출력
- 예외처리 => 예외가 발생할 수 있는 값만을 빼고, 나머지는 정상처리로 유지시키기 위한 기능
- try ~ catch
- try ~ catch ~ finally
- try : 예외가 발생할 가능성이 있는 구문 작성
- catch : try 구문에서 발생한 예외를 처리
- finally : try 구문과 상관없이 반드시 처리되어야 하는 구문을 작성 (생략가능)
try {
System.out.println(1); // 1을 출력
System.out.println(2); // 2를 출력
System.out.println(1 / 0); // 여기서 ArithmeticException 발생
} catch (Exception e) {
e.printStackTrace(); // 예외의 스택 트레이스를 콘솔에 출력
System.out.println("예외가 발생했습니다~!!"); // 사용자에게 예외 발생 알림
}
System.out.println(4); // 4 출력
System.out.println(5); // 5 출력
System.out.println(6); // 6 출력
System.out.println(7); // 7 출력
결과
1
2
java.lang.ArithmeticException: / by zero
at java_project/day06.Exception01.main(Exception01.java:22)
예외가 발생했습니다~!!
4
5
6
7
🔷 ArithmeticException : 0으로 나누었을 때 발생하는 Exception
- 예제 : 간단한 계산기. 두 숫자와 연산자를 입력받아 4칙 연산을 수행, 0으로 나누기 같은 예외 상황을 처리
- 만약 연산자가 나누기('/') 또는 나머지('%')이고, 두 번째 숫자가 0이면 RuntimeException을 발생
- 예외처리 : 예외가 발생하면 catch 블록에서 해당 예외의 스택 트레이스와 메시지를 출력. 이로 인해 프로그램은 중단되지 않고, 이후의 코드는 정상 실행
public class Exception02 {
public static void main(String[] args) {
// ArithmeticException : 0으로 나누었을 때 발생하는 Exception
Exception02 ex02 = new Exception02();
try {
// 예외가 발생할 수 있는 구문 작성
System.out.println(ex02.calc(1, 2, '+')); // 3 출력
System.out.println(ex02.calc(1, 2, '-')); // -1 출력
System.out.println(ex02.calc(1, 2, '*')); // 2 출력
System.out.println(ex02.calc(1, 0, '/')); // 예외 발생
} catch (Exception e) {
// 예외 처리 작성
e.printStackTrace(); // 예외의 스택 트레이스를 출력
System.out.println(e.getMessage()); // 예외 메시지 출력
}
System.out.println(ex02.calc(1, 2, '-')); // -1 출력
}
}
public double calc(int num1, int num2, char op) throws RuntimeException {
double res = 0;
// 연산자가 / % 인 경우 num2가 0이면 예외 발생시키기
if ((op == '/' || op == '%') && num2 == 0) {
throw new RuntimeException("num2는 0이 될 수 없습니다.");
}
switch (op) {
case '+':
res = num1 + num2;
break;
case '-':
res = num1 - num2;
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num1 / num2;
break;
case '%':
res = num1 % num2;
break;
default:
// 예외 발생
throw new RuntimeException(op + "는 산술연산자가 아닙니다.");
}
return res;
}
출력 결과
3.0
-1.0
2.0
java.lang.RuntimeException: num2는 0이 될 수 없습니다.
at Exception02.calc(Exception02.java:12)
num2는 0이 될 수 없습니다.
-1.0
🔷 자주 발생하는 예외 코드들
- ArithmeticException : 0으로 나누었을 때 발생
- ArrayIndexOutOfBoundsException : 배열의 index가 범위를 벗어났을 때 발생
- NullPointerException : 객체의 값이 null일 경우, 혹은 객체 자체가 없을 경우
- ClassCastException : 다운 캐스팅이 잘못 되었을 경우
i <= arr.length로 설정되어 있어 ArrayIndexOutOfBoundsException이 발생
- arr.length는 5이므로 유효한 인덱스는 0부터 4까지. i가 5일 때 arr[i]에 접근하면 예외 발생.
// int arr[] = null;
int arr[] = new int[5];
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]);
}
🔷 체크 예외와 언체크 예외
| 체크 예외(Checked Exception) | 언체크 예외(Unchecked Exception) | |
| 처리여부 | 반드시 예외를 처리해야 함 | 명시적인 처리를 강제하지 않음 |
| 확인시점 | 컴파일 단계 | 실행단계 |
| 예외발생시 트랜잭션 처리 |
roll-back 하지 않음 | roll-back 함 |
| 대표 예외 | Exception의 상속받는 하위 클래스 중 Runtime Exception을 제외한 모든 예외 * IOException * SQLException |
RuntimeException 하위 예외 * NullPointerException * IllegalArgumentException * IndexOutOfBoundException * SystemException |
- 체크 예외 - 체크 예외는 예외 발생 트랜잭션 처리시 롤백되지 않고, 커밋이 완료된다. 컴파일 시점에 예외를 체크하고, 예외가 발생할 가능성이 있는 경우 반드시 처리해야 한다. 예를 들어, 파일 입출력 관련 예외가 여기에 해당.
- 언체크 예외 - 주로 런타임 시 발생. 컴파일 시점에 체크되지 않는다. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException 등이 여기에 해당. 예외 발생 트랜잭션 처리 시 롤백.
🔷 멀티 캐치 구문, 다중 캐치 구문
- 예외를 구체적으로 세분화해서 잡고싶을 때 => 멀티 캐치
- 모든 예외의 최고 조상 : Exception => 어떤 예외가 발생하든지 다 캐치
try{
}catch(예외클래스명1 객체){
}catch(예외클래스명2 객체){
}
public class ExceptionHandling {
public static void main(String[] args) {
int res = 0;
try {
// 예외 발생 가능 코드
// int arr[] = null;
// arr[1] = 3;
// int arr1[] = new int[3];
// arr1[5] = 3;
res = 1 / 0;
} catch (NullPointerException e) {
System.out.println("객체가 null입니다.");
e.printStackTrace();
} catch (ArithmeticException e) {
System.out.println("0으로 나누었습니다.");
e.printStackTrace();
} catch (Exception e) {
// 최고 조상은 가장 마지막에 처리
e.printStackTrace();
}
System.out.println("종료");
}
}
- NullPointerException: Null 객체 참조
- ArithmeticException: 0으로 나누었을때
- Exception: 그 외 모든 예외를 처리.
0으로 나누었습니다.
java.lang.ArithmeticException: / by zero
at ExceptionHandling.main(ExceptionHandling.java:10)
종료
🔷 I/O 예외처리
- 파일 읽기, 쓰기 또는 사용자 입력을 처리할 때 자주 발생. 특히 콘솔에서 입력을 받거나 파일을 다룰 때 IOException이 자주 발생.
package day07;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Exception05 {
public static void main(String[] args) {
// I/O Exception 발생 예제
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String name;
try {
//콘솔에서 입력 받아서 그걸 name에서 받아라.
name = br.readLine();
System.out.println(name);
br.close();
isr.close();
name = br.readLine();
} catch(Exception e) {
e.printStackTrace();
}
}
}
InputStreamReader와 BufferedReader를 사용하여 콘솔에서 입력된 문자열을 읽고 출력
hong
hong
java.io.IOException: Stream closed
at java.base/java.io.BufferedReader.ensureOpen(BufferedReader.java:122)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:319)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at java_project/day07.Exception05.main(Exception05.java:20)
"실수는 피할 수 없지만, 그로부터 배우는 것은 우리의 선택이다."
'백엔드 > Java' 카테고리의 다른 글
| Java 익명 클래스(Anonymous Class) (0) | 2024.10.20 |
|---|---|
| Java 예외 처리 실습 (1) | 2024.10.20 |
| Java 날짜와 시간 (0) | 2024.10.16 |
| Java로 고객 관리 시스템 구현 (2) | 2024.10.15 |
| 객체지향 프로그래밍 (1) | 2024.10.14 |