예외(Exception) 처리
- 예외도 클래스이다. (Throwable 에서 상속 받았다.)
Throwable (interface) - Exception - RuntimeException (프로그램으로 처리할 수 있는 오류)
- Error (예시 : 메모리 부족)
- Exception : 실행 도중 발생할 수 있는 여러 가지 예외적인 상황 ( 코드에 의해 수습될 수 있는 미약한 오류) (오류(error))
java 에서의 오류(error) = 코드에 의해 수습될 수 없는 심각한 오류이다.
RuntimeException
1) 처리하지 않아도 되는 Exception = Uncatched Exception
2) 반드시 처리해야하는 Exception = Catched Exception : 메소드를 설계할 때 부터 익셉션을 처리하도록 설계된 Exception
처리 방법 | |
1) 개발자가 직접 처리 try { // 익셉션이 발생할 코드 } catch ( Exception e ) { // 처리하는 코드 } catch ( Exception e ) { // 처리하는 코드 } finally{ // 마지막 클린업 해주는 코드 // finally 오기전에 System.exit(0) 을 만나면 finally 블럭까지 오지 못 한다. // return 을 만나면 finally 블럭을 처리하고 반환된다. } |
try { } catch( Exception e ){ } finally { } - 하나의 try블록은 여러개의 exception 을 가질 수 있다. (하나도 없는 것도 가능하다.) - if 문과 달리 블럭 내에 포함된 문장이 하나뿐이어도 괄호를 생략하면 안된다. |
예외 없는 상황
package myexception;
public class ExceptionTest01 {
public static void main(String[] args) {
String[] ary = {"1","2","abc"};
int x = Integer.parseInt(ary[0]);
int y = Integer.parseInt(ary[1]);
double result = x/(double)y;
System.out.println("연산 결과: " + result);
}
}
예외 상황 1
package myexception;
public class ExceptionTest01 {
public static void main(String[] args) {
try {
String[] ary = {"1","0","abc"};
int x = Integer.parseInt(ary[0]);
int y = Integer.parseInt(ary[1]);
double result = x/y;
System.out.println("연산 결과: " + result);
} catch(ArithmeticException e) {
System.out.println(e.getMessage());
e.printStackTrace(); // 스택에 쌓인 오류를 추적
}
}
}
오류 : Exception in thread "main" java.lang.ArithmeticException: / by zero at myexception.ExceptionTest01.main(ExceptionTest01.java:13)
코드 | 의미 |
System.out.println(e.getMessage()); | ' by zero ' 메세지를 출력 |
e.printStackTrace(); | 스택에 쌓인 오류를 추적 |
오류상황 그 외
package myexception;
public class ExceptionTest01 {
public static void main(String[] args) {
try {
//String[] ary = {"1","2","abc"};
String[] ary = {"1","0","abc"};
int x = Integer.parseInt(ary[0]);
// int y = Integer.parseInt(ary[1]);
//int y = Integer.parseInt(ary[2]);
int y = Integer.parseInt(ary[3]);
// double result = x/(double)y;
double result = x/y;
System.out.println("연산 결과: " + result);
} catch(ArithmeticException e) {
System.out.println(e.getMessage());
e.printStackTrace(); // 스택에 쌓인 오류를 추적
}catch(NumberFormatException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return; // 무조건 finally를 들른다. -> 반환
// System.exit(0); // 들르지 않는다. -> 처리 안 하고 반환
}finally {
System.out.println("반드시 들러야 하는 블럭");
}
System.out.println("마지막 처리하는 코드");
}
}
코드 | 의미 |
return; | 무조건 finally를 들른다. |
System.exit(0); | finally 들르지 않는다. |
System.out.println("마지막 처리하는 코드"); |
- return; -> 반환 - System.exit(0); -> 처리 안 하고 반환 |
오류 직접 발생
package myexception;
public class ExceptionTest02 {
public static void main(String[] args) {
int a = 12, b = -10;
int c = 0;
try {
c = add(a,b);
}catch(Exception e) {
e.printStackTrace();
return;
}
System.out.println("결과는 " + c);
}
// y는 절대 음수일 수 없는 상황이라고 가정
public static int add(int x, int y) throws Exception {
if(y < 0) {
// 강제 exception
throw new Exception("y 값은 음수가 될 수 없습니다.");
}
int result = x + y;
return result;
}
}
코드 | 의미 |
public static int add(int x, int y) throws Exception { if(y < 0) { throw new Exception("y 값은 음수가 될 수 없습니다."); } |
키워드 throws 를 사용하여 예외 처리 선언 |
# main 바깥으로 (권장 사항은 아님)
현재 발생한 익셉션을 내부에서 해결하지 않고 바깥으로 던진 것 이다.
package myexception;
public class ExceptionTest02 {
public static void main(String[] args) throws Exception {
int a = 12, b = -10;
int c = 0;
c = add(a,b);
System.out.println("결과는 " + c);
}
// y는 절대 음수일 수 없는 상황이라고 가정
public static int add(int x, int y) throws Exception {
if(y < 0) {
// 강제 exception
throw new Exception("y 값은 음수가 될 수 없습니다.");
}
int result = x + y;
return result;
}
}
package myexception;
public class ExceptionTest02 {
public static void main(String[] args) {
int a = 12, b = -10;
int c = 0;
c = add(a,b);
System.out.println("결과는 " + c);
}
// y는 절대 음수일 수 없는 상황이라고 가정
public static int add(int x, int y) {
int result = 0;
try{
if(y < 0)
// 강제 exception
throw new Exception("y 값은 음수가 될 수 없습니다.");
result = x + y;
} catch(Exception e) {
e.printStackTrace();
}
return result;
}
}
multi catch Exception
package myexception;
public class ExceptionTest01 {
public static void main(String[] args) {
try {
String[] ary = {"1","0","abc"};
int x = Integer.parseInt(ary[0]);
int y = Integer.parseInt(ary[2]);
double result = x/y;
System.out.println("연산 결과: " + result);
} catch(ArithmeticException | NumberFormatException | ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
System.out.println("반드시 들러야 하는 블럭");
}
}
}
코드 | 의미 |
catch(ArithmeticException | NumberFormatException | ArrayIndexOutOfBoundsException e) { .... } |
하나씩 catch 문을 쓰는게 아닌 ' | '를 사용하여 구분시켰다. |
[문제] 키보드로부터 정수형 데이터 5개를 입력 받아 합계를 누적해서 출력하시오.
<실행 예시>
값 입력 : 1
현재까지 합계 : 1
값 입력 : 3
현재까지 합계 : 4
값 입력 : a
현재까지 합계 : 4
값 입력 : 3
현재까지 합계 : 7
값 입력 : b
현재까지 합계 : 7
main
package myexception;
import java.util.Scanner;
public class ExceptionTest04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int total = 0;
int num;
for(int i = 0 ; i< 5; i++) {
try {
System.out.printf("%d 번째 값 입력 >> ", i+1);
num = scanner.nextInt(); // 예외가 발생할 코드
scanner.nextLine();
total += num;
System.out.println("현재까지 합계 = " + total);
}
catch(Exception e) {
scanner.nextLine();
--i;
continue;
}
}
System.out.println("## 프로그램을 종료합니다.");
scanner.close();
}
}
scanner 를 사용해서 입력받으면 숫자만 들어올 수 있게 설정 되어 있다.. 이걸 까먹었었네..ㅜㅜ
Exception 만들기
package myexception;
// @SuppressWarnings("serial") // 시리얼 번호가 없어도 워닝을 띄우지 않게
public class MemberException extends Exception {
private static final long serialVersionUID = 1L;
// 객체 직렬화 시에 사용된다.
public MemberException(String message) {
super(message);
} // 기본생성자 + 메세지 전달
}
package myexception;
import java.util.Scanner;
public class MemberExceptionTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String userid;
while(true) {
System.out.print(">> 아이디를 2~5자 이내로 입력하세요: ");
userid = scanner.next();
try {
if(userid.length() < 2 || userid.length() > 5) {
throw new MemberException("## 아이디를 2~5자 이내로 입력하세요!!!");
} else {
System.out.println("Gooood~");
break;
}
}catch(MemberException e) {
System.out.println(e.getMessage());
scanner.nextLine();
continue;
}
}
}
}
>> 아이디를 2~5자 이내로 입력하세요: w2e34567
## 아이디를 2~5자 이내로 입력하세요!!!
>> 아이디를 2~5자 이내로 입력하세요: cvfg
Gooood~
'국비 교육 > 백엔드(Java, Spring)' 카테고리의 다른 글
[자바] 입출력 I/O 와 Stream (0) | 2024.01.30 |
---|---|
[자바] LocalDate, Calendar, Anonymous (0) | 2024.01.30 |
[자바] String 예제 - 주민번호 검증 프로그램 (0) | 2024.01.29 |
[자바] 자바 주요 API - String (0) | 2024.01.29 |