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
복사
•
예외 발생 메시지, 파일명, 라인