-
예외 처리(Exception)개발/자바JAVA 2024. 2. 5. 12:19
▶프로그램 오류
> 프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것, 프로그램 에러라고도 함.
▶오류의 종류
◆ 시스템 에러 : 컴퓨터의 오작동으로 인해 발생하는 에러
> 개발자가 소스코드로 해결 안됨.(제일 심각함)
◆ 컴파일 에러 : 소스코드가 컴파일 되는 시점에서 발생하는 에러(소스코드 상의 문법적인 문제로 발생)
> 소스코드 수정으로 해결(빨간 밑줄로 오류를 표시해줌)
◆ 런타임 에러 : 컴파일된 프로그램 코드가 "실행" 되는 시점에서 발생하는 에러
(소스코드 상의 문제는 없는데, 실행중에 발생)
> 사용자의 잘못일수도 있고, 개발자가 예측가능한 경우를 제대로 처리 안해놓은 잘못일수도 있음.
◆ 논리 에러 : 소스코드 상의 문법적인 문제도 없고, 실행했을 때도 굳이 문제가 되지 않지만,
프로그램 의도 상 내가 의도하지 않은 대로 코드가 흘러갈 경우▷이러한 "예외"들이 "발생" 했을 경우에 대비해서 "처리" 하는 방법을 정의해두는 것을 "예외처리" 라고 함!!!!
▷ 예외처리 해야하는 이유 : 예외 발생 시 프로그램이 비정상적으로 종료되는 상황을 막고자 하기 위함
(조건문 같은 느낌임)조건문으로 충분히 해결 가능 : 예외 자체가 발생 안되게끔 개발자가 소스코드로 핸들링 하는 것(예방, 예외처리x)
예외처리 구문으로 해결 가능 : 예외가 발생했을 경우를 대비해서 실행할 구문을 정의해두는것(수습)▶예외 클래스 계층 구조
> Exception과 Error 클래스 모두 Object 클래스의 자손이며 모든 예외의 최고 조상은 Exception 클래스
unchecked : 예외처리 안해도 됨.
checked : 예측 불가능한 오류/ 예외처리를 무조건 해야함
▶ UncheckedException
> 프로그램 실행 시 발생되는 예외 클래스들의 부모클래스
-예측이 가능한 상황 : 조건문으로 해결(권장)
> RuntimeException관련된 예외는 충분히 예측 가능하기 떄문에 조건문으로 해결하는 것을 권장
--> 즉, 예외처리가 필수가 아닌 "Unchecked Exception" 계열임!!◈ RuntimeException 의 자식클래스들
1. ArrayIndexOutOfBoundsException : 배열의 부적절한 인덱스로 접근할 때 발생
2. NegativeArraySizeException : 배열의 크기를 음수로 지정할 경우 발생
3. ClassCastException : 허용할 수 없는 형변환이 진행될 경우 발생(상속관계 아닐때)
4. NullPointerException : 참조할 주소값이 null인데 접근하려고 할때 발생
5. ArithmeticException : 나누기 연산시 0으로 나눌 때 발생.
>이러한 RuntimeException 과 관련된 예외는 충분히 예측 가능한 상황임.
--> 예외 자체가 발생이 애초에 안되게끔 "조건문" 으로 충분히 해결 가능한 오류들임.
=굳이 "예외처리" 를 안해도 처리 가능함 ( == Unchecked Exception)◈ ArithmeticException(나누기 연산시 0으로 나눌때 발생)
public void method1() { System.out.println("첫번째 정수 : "); int num1 = sc.nextInt(); sc.nextLine(); System.out.println("두번째 정수(0제외) : "); int num2 = sc.nextInt(); sc.nextLine(); System.out.println("결과 : " + (num1/num2)); System.out.println("프로그램 종료"); }
>두번째 정수에 0을 입력하면 이 오류가 뜬다
해결방법1 ) 그냥 조건문으로 처리해도 되지만(예방) 이는 예외사항을 미리 알 경우만 사용가능하다.
해결방법2 ) 예외가 발생했을 경우를 대비해서 실행할 내용을 정의해 두는것(수습)
바로 try ~catch문 을 이용하는 것.
: 예외가 발생할 법한 구문을 실행시키고, 거기서 예외가 발생한다면 그 때 실행할 구문을 선택적으로 실행될 수
있게끔 흐름을 잡아채는 구문임.[표현법]
try{
예외가 발생할법한 구문
}catch(발생할예외클래스 변수명){
(관례상e)
해당 예외가 발생할 경우 실행할 구문
}public void method1() { System.out.println("첫번째 정수 : "); int num1 = sc.nextInt(); sc.nextLine(); System.out.println("두번째 정수(0제외) : "); int num2 = sc.nextInt(); sc.nextLine(); try { System.out.println("결과 : " + (num1/num2)); }catch(ArithmeticException e) { System.out.println("0으로는 나눌 수 없습니다."); e.printStackTrace(); // 어디서 예외가 발생했는지 추적하기 위함(개발단계에서 쓰임) } System.out.println("프로그램 종료"); }
이렇게 try ~catch 문으로 잡아주면 된다.
◈ 처리할 예외가 2개이상일 경우(다중catch블럭)
public void method2() { try { System.out.println("정수 입력(0제외) :"); int num = sc.nextInt(); // 정수 이외의 값을 입력하면 오류가 발생할 수 있음. sc.nextLine(); System.out.println("나눗셈 연산 결과 : " + (10/num)); //num이 0이면 오류가 발생함. }catch(ArithmeticException e) { //연 System.out.println("0으로 나눌 수 없습니다."); }catch(InputMismatchException e) { // 정수값이 올바르지 않을 경우 오류 System.out.println("정수를 제대로 입력해야 합니다."); } System.out.println("프로그램 종료"); }
> catch를 하나만 쓸 경우 2가지를 다 잡을 수 없다.
◈ ArrayIndexOutOfBoundsException : 배열의 부적절한 인덱스로 접근할 때 발생하는 예외
NegativeArraySizeException : 배열의 크기를 음수로 지정할 경우 발생하는 예외
public void method3() { System.out.println("배열의 크기 : "); int size = sc.nextInt(); sc.nextLine(); try { int arr[] = new int[size]; //>size가 0보다 작다면 NegativeArraySizeException 발생 System.out.println("100번 인덱스 값 : " + arr[100]); //size가 100이하라면 (99번째 방까지 있는 배열이라면) //ArrayIndexOutOfBoundsException 발생 }catch(NegativeArraySizeException e) { System.out.println("배열의 크기를 음수로 지정할 수 없습니다."); }catch(ArrayIndexOutOfBoundsException e) { System.out.println("입력한 배열의 크기가 출력할 배열의 값보다 커야합니다."); } System.out.println("프로그램 종료"); }
위와같이 예외처리를 여러가지 쓸 수도 있지만, RuntimeException클래스 하나만 써서, 한번에 처리할 수도 있음!!(다형성)
◈ RuntimeException클래스 하나만 써서, 한번에 처리(다형성활용)
public void method4() { System.out.println("배열의 크기 : "); int size = sc.nextInt(); sc.nextLine(); try { int arr[] = new int[size]; System.out.println("100번 인덱스 값 : " + arr[100]); }catch(RuntimeException e) { // 다형성을 적용하여 부모 타입의 예외 클래스 하나로 자식타입의 예외를 모두 잡을 수 있음. System.out.println("배열의 크기를 음수로 지정했거나, 부적절한 인덱스로 접근했음."); //catch블럭이 줄어들긴 할테지만, 정확한 종류의 예외를 알려줄 수 없음. } System.out.println("프로그램 종료"); }
>다형성 적용 및 다중 catch블럭 이용시 주의할 점!!
해당 catch블럭이 한번 실행되면 -> 아예 try ~ catch 블럭을 빠져나감.
-> 다중 catch블럭은 작성 순서가 중요함.
범위가 작은 자식 타입의 예외 클래스 먼저 기술해야함!!.
(RuntimeException다음에 ArrayIndexOutOfBoundsException이거 못씀.)▶ CheckedException
> CheckedException 반드시 예외처리를 해줘야 하는 예외들 (즉, 예측 불가한 곳에서 언제 발생할지 모르기 때문에
미리 예외 처리
> 구문을 작성) >주로 외부 매체와 내 프로그램 사이의 데이터 입출력시 발생함.
> 선배개발자들이 나한테 throw한게 대부분임. 그래서 빨간 밑줄로 예외처리를 안하면 오류로 알려주는 것임◈IOException
public void method2() { // Scanner 와 같이 키보드로 값을 입력받을 수 있는 객체(단, 문자열로만 가능) BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("아무 문자열이나 입력하세요 : "); // String str = br.readLine(); // >위 메소드를 호출 시 IOException 가 발생할 수도 있음을 빨간밑줄로(컴파일에러) 알려주고 있음. // 1. try~catch문 이용해서 해결 try { String str = br.readLine(); // 문자열 길이 출력(str도 지역변수 이기 떄문에 try블록 안에서 놀아야됨) System.out.println("문자열의 길이 : " + str.length()); } catch (IOException e) { System.out.println("예외 발생됨"); } }
IOException으로 넘길수 있다.
◈ throws 이용해 예외처리해서 해결
public void method3() throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("아무 문자열이나 입력하세요 : "); String str = br.readLine(); }
나를 호출한 부분(메인클래스)으로 떠넘겨준다. 호출한 곳에서(메인클래스) 처리해줘야함.
만약 method1()에서 호출했다면 거기서 처리해주면 됨!이렇게 호출한 곳에서 처리해줄 수 있다!!
만약 여기서도 쓰기 싫다면 또 throws로 떠넘길 수 있다. 하지만 마지막에 받는곳에서 꼭 처리해줘야함!!
근데!! 메인메소드에서 마지막에서도 죽어도 처리하기 싫다?? 메인 메소드 뒤에 throws IOException 써주면 됨.
-> main까지 예외처리를 떠넘길 수 있고, main에서도 또 떠넘길 수 있다.이렇게 되면 결국 우리의 갓갓 JVM이 예외를 처리해줌.(권장x)
'개발 > 자바JAVA' 카테고리의 다른 글
java.util.Date 클래스 (1) 2024.02.11 String관련 API (1) 2024.02.11 기본API(Application Programming Interface) (0) 2024.02.02 추상클래스(Abstract Class) (0) 2024.02.02 다형성(Polymorphism) (1) 2024.01.31