
교재 : JAVA 프로그래밍 기초 - 17. 예외 처리
+ 자바의 정석[기초편]
# 프로그램 오류
[오류의 종류]
· 컴파일 에러 : 컴파일 시 발생하는 에러
· 런타임 에러 : 실행 시 발생하는 에러
· 논리적 에러 : 실행은 되지만 의도와 다르게 동작하는 것
# 런타임 에러
자바에서는 실행 시 발생할 수 있는 오류 (error와 exception)를 클래스로 정의함.
· 에러(error)
프로그램 코드에 의해서 수습될 수 없는 심각한 오류 (예 : 하드웨어 고장, 메모리 부족 등)
· 예외(exceptiom)
프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
- 정수를 0으로 나눔
- 배열의 요소 수보다 큰 요소 수를 지정해 액세스 실시
- 사용자의 입력 실수 (수치 입력 요구중인데 문자 입력 등)
- 존재하지 않는 파일을 지정하고 읽음
- 데이터베이스에 연결 불가
- 할당되지 않은 저장 영역에 액세스 (부정한 값의 포인터 참조 등)
예외 처리하기 (try - catch문) 정의
예외처리(exception handling)의
정의 : 프로그램 실행시 발생할 수 있는 예외의 발생에 대비한 코드를 작성
목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행 상태를 유지
try {
실행내용
...
} catch (예외처리문) {
예외 처리 내용
...
}
try {
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
// Exception1이 발생했을 경우, 이를 처리하기 위한 문장
} catch (Exception2 e2) {
// Exception2가 발생했을 경우, 이를 처리하기 위한 문장
} catch (Exception3 e3) {
// Exception3이 발생했을 경우, 이를 처리하기 위한 문장
}
· 하나의 try 블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 하나 이상의 catch블럭이 올 수 있다.
· 이 중 발생한 예외의 종류와 일치하는 단 한개의 catch블럭만 수행됨.
· 일치하는게 없으면 예외 처리 되지 않음.
예외처리 순서
▶ try블럭 내에서 예외가 발생한 경우
1. 발생한 예외와 일치하는 catch블럭이 있는지 찾는다.
2. 일치하는 catch블럭을 찾으면, 그 catch블럭 내의 문장들을 수행 → 전체 try - catch문을 빠져나간 후 그 다음 문장을 계속해서 수행한다.
일치하는 catch블럭을 찾지 못하면 예외는 처리되지 못한다.
▶ try블럭 내에서 예외가 발생하지 않은 경우
1. catch블럭을 거치지 않고 전체 try - catch문을 빠져나가서 수행을 계속한다.
예제
① 배열 요소수를 초과하여 액세스하고 예외처리 실행해보기
package chap17;
public class ArrayException2 {
public static void main(String[] args) {
try {
// int형 배열
int[] intArray = new int[5];
// 10엔덱스에 값을 대입
System.out.println("intArray[10]에 숫자를 할당합니다.");
intArray[10] = 50; // 최대 배열 요소수를 초과하는 대입처리
// 결과 표시
System.out.println("intArray[10]에 50을 할당하였습니다.");
} catch (ArrayIndexOutOfBoundsException e) { // 최대 배열 요소수 초과 예외처리
System.out.println("배열의 요소수를 초과했습니다.");
}
System.out.println("프로그램 종료");
}
}
▽ 실행 ▽
② 정수를 0으로 나눠서 예외처리 실행해보기
package chap17;
public class ZeroException2 {
public static void main(String[] args) {
try {
// 숫자를 0으로 나눔
int num = 10 / 0;
// 결과
System.out.println("10/0 결과: " + num);
} catch (ArithmeticException e) { // 0나누기의 예외처리
System.out.println("0으로 나눌 수 없습니다.");
}
System.out.println("처리 종료");
}
}
▽ 실행 ▽
③ 호출한 메소드 내에서 발생한 예외 처리 실행해보기
package chap17;
public class ThrowZeroException2 {
public static void calcTest() {
// 숫자를 0으로 나눔
int num = 10 / 0;
// 결과표시
System.out.println("10/ 결과: " + num);
}
public static void main(String[] args) {
try {
// calcTest메소드 호출
calcTest();
} catch (ArithmeticException e) { // 0나누기 예외처리
System.out.println("0으로 나눌 수 없습니다.");
}
System.out.println("처리 완료");
}
}
▽ 실행 ▽
※ 예외가 발생했을 경우 예외 처리가 행해지고 있는지의 여부가 호출처에서 호출원으로 거슬러 간다.
예외 클래스의 계층구조
catch(Exception e) {
…
}
모든 예외 클래스는 Exception클래스의 자손이므로,
catch블럭의 괄호()에 Exception클래스 타입의 참조변수를 선언해 놓으면
어떤 종류의 예외가 발생하더라도 이 catch블럭에 의해 처리됨.
finally블럭
예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용
try {
// 예외가 발생할 가능성이 있는 문장
} catch (Exception e) {
// 예외 처리를 위한 문장
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장
}
finally블럭은 try - catch문의 가장 마지막에 위치해야한다.
예제 ①
package chap17;
public class FinallyBlock {
public static void main(String[] args) {
try {
// int형 배열
int[] intArray = new int[5];
// 배열에 값을 할당
System.out.println("배열에 숫자를 할당합니다.");
intArray[10] = 50; // 예외를 일부러 발생시키는 대입
// intArray[0] = 50; // 올바르게 할당
// 결과 표시
System.out.println("배열에 50을 할당했습니다.");
} catch (ArrayIndexOutOfBoundsException e) { // 최대 배열요소수를 초과하는 예외 처리
System.out.println("배열의 요소수를 초과했습니다.");
} finally {
System.out.println("예외처리의 마지막 처리입니다."); // finally블록
}
System.out.println("처리 종료");
}
}
▽ 실행 ▽
예외 처리 패턴
① try-catch(필수)
② try-catch-finally(catch가 있는 경우는 임의 설정)
③ try-(catch* 임의의 수)-finally(catch가 있는 경우는 임의 설정)
④ try-finally(필수)
[예외 처리 용어]
· 예외를 throw한다 : 프로그램 실행중 에러가 발생하는 것
· 예외 catch(잡기) : catch문의 매개 변수와 발생한 예외 객체가 일치하는 것
처리내용
try {
// try내부문장
} catch (예외클래스명 인수명) {
// 예외처리 내용
} finally {
// 예외중 catch문내에 포함이 안되는 경우
}
처리내용
checked예외 & unchecked예외
체크(checked)예외 : 예외 처리를 기술하지 않으면 컴파일 에러가 되는 예외
비체크(unchecked)예외 : 예외 처리를 기술하지 않아도 컴파일할 수 있는 예외
체크(checked)예외 | 비체크(unchecked)예외 |
ArithmeticExceptio | IOExceptiuon |
NullPointerException | ClassNotFoundException |
ArrayIndexOutOfBoundsException | FileNotFoundException |
IndexOutOfBoundsException | |
ArrayStoreException | |
ClassCastException | |
NoSuchFieldException | |
NoSuchMethodException | |
RuntimeException | |
IllegalAccessException | |
NumberFormatException |
# 연습문제
17.5 연습문제
<질문 1 >다음의 질문 ①~⑤에 대해 ○인가×로 대답하십시오.
① 예외가 발생하면 반드시 catch 블록이 처리된다. X
② 예외가 발생하지 않는 경우에도 반드시 finally 블록 내의 처리가 실행된다. O
③ catch 블록은 복수 설정할 수 있으므로, catch 블록에 지정하는 예외 클래스의 배열은 특별히 신경쓸 필요는 없다. X
④ catch의 「()」괄호내에 지정한 변수명을 이용하면, 예외의 상세한 정보를 취득할 수 있다. O
⑤ 예외처리를 짜면 소스코드가 번잡해지므로 어떤 예외도 절대로 처리할 필요는 없다. X
<질문 2> 아래에 표시된 소스 코드를 실행 한 결과로 올바른 것을 대답하십시오.
① red만 화면에 표시된다.
② red, blue, yellow, pink, black 모두 표시된다.
③ red, blue, pink, black이 표시된다.
④ yellow만 화면에 표시된다.
⑤ red, blue, yellow, 핑크가 표시된다.
⑥ black만 화면에 표시된다.
package chap17exercise;
public class Practice2 {
public static void main(String[] args) {
System.out.println("red");
try {
int[] array = new int[2];
System.out.println("blue");
array[2] = 88;
System.out.println("yellow");
} catch (Exception e) {
System.out.println("pink");
} finally {
System.out.println("black");
}
}
}
<질문 3> 이하에 나타내는 Practice03.java의 소스 코드를 실행했을 경우, 발생할 가능성이 있는 선택사항의 예외를 ○인가×로 대답해 주세요.
① 파일 입출력 에러(ioexception) X
② 0 나누기 에러(arithmeticexception) O
③ 배열 에러(arrayindexoutofboundsexception) O
④ 형식 변환 에러(numberformatexception) X
⑤ 키보드 입력값의 에러(inputmismatchexception) O (int형외에 다른값을 넣으면 에러)
package chap17exercise;
import java.util.*;
public class sample {
public static void main(String[] args) {
int cnt = 0; // 입력수
int sum = 0; // 총점
int ave = 0; // 평균 (소수점 이하는 자름)
int[] num = new int[3]; // 입력숫자 저장하는 배열
Scanner sin = new Scanner(System.in); // scanne클래스 객체화
// 반복처리 (배열의 요소수)
while (true) {
// 키보드에서 숫자 입력하고 배열에 저장
System.out.print("(숫자 입력(999에서는 강제종료)): ");
int tmpnum = sin.nextInt();
// 입력값이 999이면 강제 종료
if (tmpnum == 999) {
break;
}
num[cnt] = tmpnum; // 배열에 데이터 자정
cnt++; // 입력수 계산
}
// 반복처리(배열의 요소수분)
for (int i = 0; i < cnt; i++) {
// 입력수치를 총점에 추가
sum += num[i];
}
// 평균 계산
ave = sum / cnt;
// 각 결과를 화면에 출력
System.out.println("입력수: " + cnt );
System.out.println("총점: " + sum );
System.out.println("평균점:" + ave );
}
}
<질문 4> 질문 3에서 키보드 입력 값에 대한 예외를 처리했지만 그 이외에도 다음과 같은 예외가 발생합니다.
- 1명도 입력하지 않고 종료한 경우: 0 나누기 예외
- 4회 이상 입력한 경우: 최대 배열 요소 수 초과 예외
위를 다루는 각 예외를 가공하는 것과 같은 예외 처리를 통합한 practice1701.java를 창조하십시오.
질문3에서 작성한 소스 코드를 이용해, 변경 사양에 따라 작성해 주세요.
변경사양
- try 블록에 포함시키는 처리는 main 함수 내의 모든 처리를 포함한다.
- catch 하는 예외는 Exception를 지정한다.
- catch 블록 내의 처리는 예외의 상세 정보를 화면에 출력한다.→「xxxx라는 예외가 발생했습니다.」
※xxxx=예외의 상세 정보
package chap17exercise;
public class Sample {
public static void main(String[] args) {
try {
main
} catch(...) {
오류처리
}
}
}
package xyz.devbro.chap17;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Practice1701 {
public static void main(String[] args) {
try {
int cnt = 0;
int sum = 0;
int ave = 0;
int[] num = new int[3];
Scanner sc = new Scanner(System.in);
while(true) {
try {
System.out.print("숫자입력 (999입력시 종료): ");
int tempNo = sc.nextInt();
if (tempNo == 999) {
break;
}
num[cnt] = tempNo;
cnt++;
} catch (InputMismatchException e) {
System.out.println("문자가 입력되었습니다. 정수를 입력하세요");
sc.next();
}
}
System.out.println("입력: " + cnt);
System.out.println("합계: " + sum);
System.out.println("평균: " + ave);
} catch (Exception e) {
System.out.println("예외 발생: " + e);
}
}
}
'Backend > JAVA' 카테고리의 다른 글
[JAVA] JAVA 프로그래밍 기초 교육 : 파일 입출력 (0) | 2022.05.27 |
---|---|
[JAVA] JAVA 프로그래밍 기초 교육 : 클래스 라이브러리(java.lang) (0) | 2022.05.27 |
[JAVA] JAVA 프로그래밍 기초 교육 : 패키지 & 임포트 (0) | 2022.05.26 |
[JAVA] JAVA 프로그래밍 기초 교육 : 클래스 멤버 & 인스턴스 멤버 (0) | 2022.05.26 |
[JAVA] JAVA 프로그래밍 기초 교육 : 생성자 & 오버로드 (0) | 2022.05.25 |