[Java] 자바 #29, 예외처리(Exception, try-catch문) 및 예외 종류 예제 및 응용
- 프로그래밍 언어/Java
- 2019. 2. 27. 22:54
예외, Exception
- 컴파일 발견 X 런타임발견 O - 실행중 발생하는 에러 - 개발자가 예측을 할수도 없을수도 있다. -> 예측을 하더라도 발생할 수 있는 에러. - 주로 발생하는 경우 : 프로그램 외부와의 소통을 하는 업무(파일 입출력, DB입출력, 네트워크 입출력 등...) |
예외처리, Exception Handling
1. 전통적인 방식. (*조건문*)
2. 특화된 구문. (**try-catch(finally)문**)
전통적인 방식( 하드코딩의 하드코딩의 하드코딩 )
사용자로부터 숫자1개 입력받기. > 업무진행.
int num = 0;
// 0이 아닐때만 일을 한다.
if (num != 0) {
// 업무 코드, *비즈니스코드*
System.out.printf("100 / %d = %d\n", num, 100 / num);
} else {
System.out.printf("0을 입력하면 안됩니다.\n");
}
//java.lang.ArithmeticException 0으로 나눈 예외
System.out.printf("100 / %d = %d\n",num,100/num);
>> 0 을 입력하면 에러가 발생한다는 상황을 개발자가 미리 인지하고 있어야 한다. 하지만 개발자는 모든 예외상황을 예측할 수 없으므로 아주 좋지 않은 방법이다.
특화된 구문을 이용한 방식( try ~ catch 구문)
// 사용자로부터 숫자1개 입력받기. > 업무진행.
int num = 0;
try {
System.out.println("테스트입니다.");
System.out.printf("100 / %d = %d\n", num, 100 / num);
System.out.println("테스트입니다.");
} catch (Exception e) { // 가인자값.
System.out.printf("0을 입력하면 안됩니다.\n");
// 예외처리 코드.
System.out.println(e.getMessage());
System.out.println(e.toString());
System.out.println(e.getStackTrace());
- 위 3개는 에러메시지 출력하게 해줌. 각각 다르니 꼭 출력해보세요.
}
예외 종류
1. java.lang.ArithmeticException : 0으로 나눈 예외
>> 전통적인 예외처리에 있는 코드처럼 100/0 처럼 분모에 0이 있을 때 발생하는 예외이다. 계산과정을 사용하지 않는 한 잘 나타나지는 않는다.
2. java.lang.ArrayIndexOutOfBoundsException
>> 배열의 인덱스로 배열의 요소를 접근하려고 할때 [ ] 안에 알맞은 값을 넣지 않은 경우에 나타난다. 예를들어 0보다 작은 값을 배열의 [ ] 안에 넣거나 배열의 length-1(가장 마지막 배열의 위치는 항상)보다 큰 값을 넣었을 때 나타난다.
3. java.lang.NullPointerException
>> 변수에는 아직 객체생성이 일어나지 않았는데 해당 객체를 호출하여 객체에 있는 메소드를 호출한다거나 할 때 발생. 아래의 예제에서는 Random 객체에 new 키워드를 사용하여 객체 생성을 하지 안았기 때문에 변수안에 아무것도 없는데(null) nextInt 메소드를 사용하려고 하였기 때문에 발생.
4. java.lang.ClassCastException
>>타입변환을 할 수 없는 타입으로 형변환을 진행하려고 할 때 발생한다.
ex) 2, 3, 4 예제
// 배열 > index 처리 > 예외 발생
int[] nums = { 10, 20, 30 };
java.lang.ArrayIndexOutOfBoundsException
try {
nums[3] = 40;
System.out.println(nums[3]);
} catch (Exception e) {
System.out.println("배열 첨자 오류");
}
java.lang.NullPointerException
try {
Random ran = null;
System.out.println(ran.nextInt(10));
} catch (Exception e) {
System.out.println("랜덤 객체 없음");
}
java.lang.ClassCastException
try {
객체는 없지만 느낌만 살펴보세요.
Printer[] list = new Printer[2];
list[0] = new LG300();
list[1] = new HP400();
((LG300) list[1]).call();
} catch (Exception e) {
System.out.println("클래스 캐스팅 에러");
}
5. 예상 못한 예외는 Exception으로 흐른다.
try {
// 업무 1.
int num = 0;
System.out.printf("100 / %d = %d\n", num, 100 / num);
// 업무 2.
int[] nums = { 10, 20, 30 };
System.out.println(nums[2]);
// 업무 3.
Random ran = new Random();
System.out.println(ran.nextInt(10));
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("배열 인덱스 범위 초과");
} catch (ArithmeticException e) {
System.out.println("0으로 나눔");
} catch (NullPointerException e) {
System.out.println("널 객체 참조.");
} catch (Exception e) {
System.out.println("다른 오류 발생."); 위의 업무 3개는 각각 catch절에 예외처리를 했지만, 간혹 예기치 못한 예외가 발생하는 경우가 있다. 그러할 때를 대비하여 전체 Exception을 예외처리 해주어야한다.
}
의문점? : 그렇다면 그냥 애초에 Exception만 catch절에 해놓으면 되는거 아닌가요??
>> 그래도 되는 경우는 그래도 좋다. 하지만 프로그램을 개발할 때 예외가 발생하는 상황마다 특정한 방식으로 예외를 처리해주어야 하는 경우가 있다. 각각의 해결방안이 다르다는 것을 인지해야 한다. 이건 개발을 많이 해보다보면 자연스럽게 알게 될것이다.
예외 발생시키기 & 예외 미루기
개발자가 강제로 예외를 발생시킴 > 예외 발생시키기
// throw new Exception("3의 배수가 아닙니다"); //반드시 조건부로 한다.
throw new Exception("A001"); // 각종 예외상황을 미리 설정하고 , 조사를해놓고 넘버링을 한것. 표준화
"A001" 같은 코드는 비즈니스적인 프로그래밍을 할때 예외상황을 미리 파악하여 코드화해놓은 것이고 다른 사람이 에러를 봣을 때 어떤 에러유형인지 파악하기 쉽게 정리해놓은 문서에 코드를 써서 관리하는 상황을 나타낸 것. |
예외 미루기
상황 : 어떤 회사는 제주, 광주, 부산의 지사가 있다. 본점은 서울이라고 할때 어떤 문제가 생기면 본사로 문제상황을 넘겨주어야 하는데 이러한 상황을 자바코드로 예를 들면 다음과 같다.
private static void 본사() {
try {
부산지사();
광주지사();
제주지사();
} catch (Exception e) {
예외처리 코드();
}
}
private static void 제주지사() throws Exception {
int n = 0;
System.out.println(100 / n); 에러
}
private static void 광주지사() throws Exception {
Random ran = null;
System.out.println(ran.nextInt(10)); 에러
}
private static void 부산지사() throws Exception {
int[] nums = { 10, 20, 30 };
System.out.println(nums[3]); 에러
}
>> 예제설명 : 본사() 메소드에서 제주지사(), 광주지사(), 부산지사() 메소드를 호출하였다. 각각의 지사메소드에서 예외가 발생할 경우 예외 처리를 해주어야하는데 바로 처리하지 않고 예외를 발생시킨 코드를 호출한 곳으로 그 예외를 넘겨버린다. 즉, 지사에게 일을 시킨것은 본사이므로 이를 책임질 본사메소드로 예외를 넘겨서 본사에서 예외를 처리하여 준다!!
'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] 자바 #31, 컬렉션 프레임워크 - HashMap (2) | 2019.03.01 |
---|---|
[Java] 자바 #30, 컬렉션 프레임워크 - ArrayList (0) | 2019.03.01 |
[Java] 자바 #28, Wrapper클래스 예제 및 응용 (0) | 2019.02.25 |
[Java] 자바 #27, 제네릭(Generic) (2) | 2019.02.24 |
[Java] 자바 #26, 열거형(Enumeration, enum) (0) | 2019.02.24 |