package ex_exception;
import java.io.*;
public class Ex1 {
public static void main(String[] args) {
/*
* 하나의 try 블록에서 복수개의 예외를 처리하는 경우
*
* < 기본 문법 >
*
* try {
*
* // 예외 발생1 코드
* // 예외 발생2 코드
* // 예외 발생3 코드
* // 예외 발생4 코드
*
* } catch (예외발생1클래스 변수명) {
* // 예외발생1 코드에서 예외 발생 시 처리할 코드들...
*
* } catch (예외발생2클래스 변수명) {
* // 예외발생2 코드에서 예외 발생 시 처리할 코드들...
*
* } catch (예외발생3클래스 | 예외발생4클래스 변수명) {
* // 예외발생3 또는 예외발생4 코드에서 예외 발생 시 처리할 코드들...
*
* } catch (Exception e) {
* // 위의 모든 예외가 일치하지 않을 경우 나머지 예외를 모두 처리하는 코드들...
* // if문에서 else문과 같은 역할 수행
*
* }
*
*/
System.out.println("프로그램 시작");
try {
// 첫번째 예외 : ArithmeticException
// int num1 = 3, num2 = 0;
int num1 = 3, num2 = 1;
System.out.println(num1 / num2);
System.out.println("===========================");
// 두번째 예외 : NullPointerException
// String str = null;
String str = "홍길동";
System.out.println(str.length());
System.out.println("===========================");
// 세번째 예외 : ArrayIndexOutOfBoundsException
int[] arr = {1};
System.out.println(arr[2]);
System.out.println("===========================");
} catch (ArithmeticException e) { // 첫번째로 확인하는 catch 블록
System.out.println("예외 발생 : 0으로 나눌 수 없습니다!");
} catch (NullPointerException e) { // 두번째로 확인하는 catch 블록
System.out.println("예외 발생 : null 값을 참조할 수 없습니다!");
} catch (Exception e) { // 마지막으로 확인하는 catch 블록
// 위의 두 가지 예외에 해당되지 않는 예외를 모두 Excetpion 타입으로 catch 함
System.out.println("예외 발생 : 나머지 예외를 모두 처리합니다!");
// => if문에서 else문 역할과 동일함
}
// System.out.println(num1); // 선언되지 않은 변수 사용 오류 발생!
System.out.println("프로그램 끝");
// try ~ catch 자동 단축키 : 예외 발생 가능성이 있는 코드를 블록 처리 후
// Alt + Shift + z -> y
try {
Class.forName(""); // ClassNotFoundException 발생 예상 코드
FileInputStream fis = new FileInputStream(""); // FileNotFoundException 발생 예상 코드
try {
System.out.println(3 / 0);
} catch (NullPointerException e) {
}
System.out.println("확인!");
} catch (ClassNotFoundException | FileNotFoundException e) {
System.out.println("ClassNotFoundException 또는 FileNotFondException 발생!");
} catch (Exception e) {
}
}
}
package ex_exception;
public class Ex2 {
public static void main(String[] args) {
/*
* Exception 객체의 정보 활용
*
*/
System.out.println("프로그램 시작!");
try {
int num1 = 3;
int num2 = 0;
System.out.println(num1 / num2);
} catch (Exception e) {
// e.printStackTrace(); // 예외 발생 시 코드의 호출 순서 및 예외 발생 상황을 출력
System.out.println("원인 : " + e.getMessage());
// ArithmeticException 발생 시 원인메세지인 "/by zero" 문자열을 리턴!
}
System.out.println("프로그램 종료!");
}
}
package ex_exception;
public class Ex3 {
public static void main(String[] args) {
/*
* try ~ catch ~ finally 구문
*
* < 기본 문법 >
* try {
* // 예외가 발생할 가능성이 있는 코드
*
* } catch (예외클래스명 변수명) {
* // 예외 발생 시 처리할 코드
*
* } finally {
* // 예외 발생 여부와 관계없이 실행할 코드
*
* }
*
*/
try {
System.out.println("1 - try 블록 시작!");
int num1 = 3, num2 = 1;
System.out.println(num1 + " / " + num2 + " = " + (num1 / num2)); // 예외가 발생하는 코드
System.out.println("2 - 예외 미발생. try 블록 끝!"); // 예외 발생 시 실행되지 못하는 코드
} catch (Exception e) { // Exception 예외를 전달받을 catch 문
System.out.println("3 - catch 블록 시작! 원인 : " + e.getMessage());
} finally {
System.out.println("4 - finally 블록 시작! 언제나 실행되는 코드!");
}
System.out.println("5 - try 구문 끝!");
System.out.println("===========================================");
System.out.println("메서드 호출 시작!");
method();
System.out.println("메서드 호출 끝!");
} // main() 메서드 끝
public static void method() {
/*
* 메서드 호출 시 예외 발생 여부에 따른 처리 순서
*
* 1. 예외가 발생했을 경우
* 1 -> 예외 발생 -> 3(catch 블록 실행) -> 4(finally 블록 실행) -> 5
*
* 2. 예외가 발생하지 않을 경우
* 1 -> 연산식 -> 2 -> return문(아직 실행X) -> 4(finally 블록 실행) -> return문 실행
*/
try {
System.out.println("1 - try 블록 시작!");
int num1 = 3, num2 = 0;
System.out.println(num1 + " / " + num2 + " = " + (num1 / num2)); // 예외가 발생하는 코드
System.out.println("2 - 예외 미발생. try 블록 끝!"); // 예외 발생 시 실행되지 못하는 코드
// return; // 메서드 수행을 중단하고 호출한 곳으로 돌아감
} catch (Exception e) { // Exception 예외를 전달받을 catch 문
System.out.println("3 - catch 블록 시작! 원인 : " + e.getMessage());
return;
} finally {
System.out.println("4 - finally 블록 시작! 언제나 실행되는 코드!");
}
System.out.println("5 - try 구문 끝!");
}
}
package ex_exception;
public class Ex4 {
public static void main(String[] args) {
/*
* 예외 처리에 대한 위임(= 예외 던지기 = throws)
*
* < 기본 문법 >
*
* [제한자] 리턴타입 메서드명([매개변수]) throws 예외클래스1, 예외클래스2, .... {}
*
*/
System.out.println("프로그램 시작");
try {
팀장(); // 모든 예외가 Exception 타입으로 위임
// => try ~ catch 문을 통해 예외 처리가 필수!
// 현재 위치가 main() 메서드에서 위임할 경우
// JVM에서 예외 처리를 한다! => 예외 발생!
// => 최종 메서드인 main() 메서드에서 반드시 try ~ catch 문 사용!
} catch (Exception e) {
// 던진 예외에 대해서 영역 축소는 불가능!
System.out.println("main() 메서드에서 최종적으로 모든 예외 처리!");
}
System.out.println("프로그램 종료");
}
public static void 팀장() throws Exception{
// 팀장() 메서드에서 직접 위임된 예외를 처리
// try {
// 대리(); // ArithmeticException, NullPointerException 예외가 발생, 직접 처리한 예외는 제외
// // => 나머지 예외만 위임
//
// } catch (NullPointerException e) {
// System.out.println("팀장이 NullPointerException 예외를 직접 처리!");
// }
// 팀장() 메서드를 호출한 곳으로 예외 위임!
대리();
// => 모든 예외를 하나로 묶어서 위임하려면
// 1. Exception 으로 모든 예외 통합
// 2. RuntimeException으로 명시
}
public static void 대리() throws NullPointerException {
// 사원1에서 예외가 발했을 때 위임된 경우
// 1) 대리() 메서드에서 직접 위임된 예외를 처리
try {
사원1(); // ArithmeticException 예외 위임되는 위치
사원2(); // NullPointerException 예외 위임되는 위치
} catch (ArithmeticException e) {
System.out.println("대리에서 사원1로 부터 위임받은 ArithmeticException 예외를 직접 처리!");
}
// catch (NullPointerException e) {
// System.out.println("대리에서 사원2로 부터 위임받은 NullPointerExcepion 예외를 직접 처리!");
// }
// 2) 예외를 위임하는 경우 : throws 키워드 사용
// => 대리() 메서드를 호출한 팀장() 메서드에게 발생한 예외를 던짐
// => 모든 예외를 throws로 위임해도 되고, 특정 예외만 위암한 뒤
// 나머지 예외는 직접처리 해도 된다!
}
public static void 사원2() throws NullPointerException {
String str = null;
System.out.println(str.length()); // NullPointerExcepiton 발생
// => 발생한 예외를 대리에게 위임
}
public static void 사원1() throws ArithmeticException {
// 사원1에서 예외가 발생하는 경우
// 1) 직접 예외를 처리하는 경우 : try ~ catch 문 직접 사용
// try {
// System.out.println(3 / 0); // ArithmeticException 발생
//
// } catch (ArithmeticException e) {
// System.out.println("사원1 에서 예외를 직접 처리!");
//
// }
// 2) 예외를 위임하는 경우 : thorws 키워드 사용
System.out.println(3 / 1); // ArithmeticException 발생
// => 사원1() 메서드 선언부 마지막에 throws ArithmeticException 기술!
// => 발생한 예외를 사원1() 메서드를 호출한 대리() 메서드로 던짐
}
}
연습
package ex_exception;
public class Test3 {
public static void main(String[] args) {
try {
try {
int[] i = {1};
System.out.println(i[2]); // ArrayIndexOutOfBoundsException 발생!
// String str = null;
// System.out.println(str.length()); // NullPointerException 발생!
System.out.println("출력문 1");
} catch (ArithmeticException e) {
System.out.println("출력문 2");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("출력문 3");
}
System.out.println("출력문 4");
// => 안쪽 try 블록에서 예외가 발생하지 않으면 실행, 예외가 발생하더라도 예외 처리가 되면 실행!
// 그러나 예외처리가 안될 경우 바깥쪽 catch 블록에서 예외 처리를 찾으면 실행 불가!
} catch (ClassCastException e) {
System.out.println("출력문 5");
} catch (NullPointerException e) {
System.out.println("출력문 6");
} finally {
System.out.println("출력문 7");
}
// => 모든 catch 블록이 해당 예외를 처리할 수 없으면, finally 블록 코드를 실행 후
// 예외는 처리되지 못한 채 해당 프로그램은 강제 종료!
}
}