Search

Chapter 10. 예외 처리

Created
2021/04/07 17:09
Tags

10.1 예외와 예외 클래스

에러 : 하드웨어의 오동작, 고장으로 응용 프로그램 실행 오류가 발생하는 것
JVM 실행에 문제가 발생한 것으로 대처할 방법이 없다
예외 : 에러 이외의 오류. 사용자의 잘못된 조작, 개발자의 잘못된 코딩으로 프로그램 오류가 발생하는 것
예외 처리를 통해서 프로그램을 종료하지 않고 실행이 유지되도록 대처
예외의 종류
1.
일반 예외(Exception)
컴파일러에서 검사하는 예외
2.
실행 예외(Runtime Exception)
일반 예외를 제외한 나머지 예외
자바는 예외를 클래스로 관리
JVM은 실행도중 예외가 발생하면 해당 예외 클래스로 객체를 생성 → 예외 처리 코드에서 해당 객체를 이용
모든 예외 클래스는 'java.lang.Exception' 클래스를 상속받는다.
JVM은 'RuntimeException' 클래스 상속 여부를 보고 실행 예외를 판단한다.

10.2 실행 예외

실행 예외는 자바 컴파일러가 체크하지 않기 때문에 개발자가 직접 예외 처리를 해야한다.
만약 예외 처리를 하지 않으면 예외 발생 시 프로그램은 바로 종료된다.

10.2.1 NullPointerException

참조하는 객체가 없는 참조 변수( 즉, 참조 변수가 null 을 가리키고 있다. )에 접근할 때 발생하는 예외
public static void main(String[] args) { String data = null; // data 변수가 가리키는 객체가 없음 data.toString(); // NullPointerException 예외 발생 }
Java
복사
프로그램에서 예외가 발생하면 콘솔뷰에 예외 메시지가 출력되면서 프로그램이 종료된다.

10.2.2 ArrayIndexOutOfBoundsException

배열의 인덱스 범위를 초과하여 사용하는 경우 발생하는 예외
길이가 2인 배열의 세번째 원소를 사용하는 경우

10.2.3 NumberFormatException

숫자로 변환할 수 없는 문자열을 포함하는 경우 발생하는 예외
포장(Wrapper) 클래스의 parse 메소드를 사용하는 경우
int a = Integer.parseInt("10"); double b = Double.parseDouble("ten");
Java
복사

10.2.4 ClassCastException

타입 변환을 할 수 없는 관계에서 타입 변환을 시도하는 경우 발생하는 예외
클래스의 상속, 인터페이스의 구현에서 자동 타입 변환 → 강제 타입 변환 관계를 어기는 경우

10.3 예외 처리 코드

프로그램에서 예외가 발생한 경우, 종료를 방지하고 정상 실행을 유지하도록 처리하는 코드
자바 컴파일러는 컴파일러 중 일반 예외가 발생할 수 있는 코드를 처리하도록 요구
실행 예외는 컴파일러가 검사하지 않기 때문에 예외 처리를 하지 않으면 프로그램이 종료된다.
try-catch-finally
생성자, 메소드 내부에서 작성한다.
try : 예외가 발생할 수 있는 코드의 위치
catch : 예외 발생 시 처리하는 코드
finally : 예외 발생 여부와 상관없이 실행되는 코드. try, catch 내부에서 return 사용시 finally는 항상 실행.
public static void main(String[] args) { try { Class cls = Class.forName("java.lang.DevPG"); // 자바 표준 API에 없는 클래스 } catch (ClassNotFoundException e) { System.out.println("This class is not exist"); } }
Java
복사

10.4 예외 종류에 따른 처리 코드

10.4.1 다중 catch

try 블록 내부에 여러개의 예외가 발생할 수 있다.
발생할 수 있는 여러 개의 예외를 처리하도록 다중 catch 코드를 작성한다.

10.4.2 catch 순서

상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다.
위와 같은 코드에서 두번째 catch 는 평생 실행되지 않는다.

10.4.3 멀티 catch

하나의 catch 블록에서 여러 개의 예외를 처리할 수 있는 방법.
서로 다른 예외를 동일하게 처리하고자 할 때 사용한다.
예외를 " | " 로 구분한다.

10.5 자동 리소스 닫기

리소스 ( 데이터를 읽고 쓰는 객체 )를 사용한 뒤에 "close()" 메소드를 실행하여 안전하게 리소스를 닫는다.
자바 7 부터 try-with-resource 를 사용하여 자동으로 리소스를 닫을 수 있다.
명시적으로 리소스 닫기
try { file = new FileInputStream("a.txt"); // 리소스 객체 생성 } catch (Exception e) { } finally { if(file!=null){ try { file.close(); // 정상/예외 모두 리소스를 안전하게 닫아야 한다. } catch (Exception e) { } } }
Java
복사
try-with-resource
try ( FileInputStream fis = new FileInputStream("a.txt"); FileOutputStream fos = new FileOutputStream("b.txt") ) { } catch ( Exception e ) { }
Java
복사
리소스 객체는 "java.lang.AutoCloseable" 인터페이스를 구현해야 한다.
try-with-resource 는 AutoCloseable 인터페이스의 close() 메소드를 호출하기 때문

10.6 예외 떠넘기기

메소드 내부에서 발생한 예외를 메소드를 호출한 곳으로 떠넘기는 방법
try-catch를 사용하지 않는다.
예외가 발생할 수있는 메소드의 선언부에 'throws' 키워드를 사용.
void method() throws Exception { ... // 예외 발생 가능 }
Java
복사
public static void main(String[] args) { try { method(); } catch ( Exception e ) { System.out.println("method()에서 발생한 예외를 떠넘김 "); } }
Java
복사
main 메소드도 JVM 에게 예외를 떠넘길 수 있지만 권장하지 않는 방법

10.7 사용자 정의 예외와 예외 발생

자바 표준 API에서 제공하는 예외 클래스 이외의 예외에 대해서 처리가 필요한 경우
Application Exception ( 사용자 정의 예외 )

10.7.1 사용자 정의 예외 클래스 선언

일반 예외(Exception 상속), 실행 예외(RuntimeException 상속)로 선언할 수 있다.
public class XXXException extends [Exception | RuntimeException] { public XXXException(); public XXXException(String msg) { super(msg); } }
Java
복사
사용자 정의 예외 클래스의 이름은 ~Exception 으로 끝나는 것이 좋다.
필드, 메소드, 생성자를 포함할 수 있지만 보통 생성자만 포함한다.
기본 생성자 + String 타입의 매개변수를 갖는 생성자 선언

10.7.2 예외 발생시키기

자바 표준 API 예외와 사용자 정의 예외를 코드에서 발생시키는 방법
throw new XXXException(); throw new XXXException("XXXException 발생");
Java
복사
throw : 예외 발생시키기 → throws : 호출한 곳으로 예외 떠넘기기
public void method() throws XXXException { throw new XXXException("XXXException 발생"); }
Java
복사
호출한 곳에서 예외 처리하기
try { method(); } catch ( XXXException e ) { // 예외처리 }
Java
복사

10.8 예외 정보 얻기

try 블록에서 예외가 발생하면 catch 블록의 매개 변수를 참조하여 해당 예외 객체의 정보를 알 수 있다.
모든 예외는 Exception 클래스를 상속하기 때문에 해당 객체에서 Exception의 메소드를 호출할 수 있다.
'getMessage()''printStackTrace()'
생성자의 매개변수로 문자열을 받는 예외 객체. 매개변수의 문자열은 객체 내부에 저장됨.
throw new XXXException("XXXException 예외 발생");
Java
복사
예외 객체의 getMessage() 메소드 사용.
try { method(); } catch ( XXXException e ) { String message = e.getMessage(); System.out.println(message); }
Java
복사
예외 객체의 printStackTrace() 메소드 사용. 더욱 상세한 내용을 출력.
try { method(); } catch ( XXXException e ) { e.printStackTrace(); }
Java
복사
예외 발생 메시지, 파일명, 라인