자바의 정석 97~103강 ch8 예외처리
ch 8-1~3 프로그램 오류, 예외 클래스의 계층구조
1. 프로그램 오류
컴파일 에러 : 컴파일할 때 발생하는 에러
런타임 에러 : 실행할 때 발생하는 에러
논리적 에러 : 작성 의도와 다르게 동작
2. 컴파일 에러
컴파일러 역할 : 구문체크, 번역, 최적화
코드를 번역 중 잘못된 코드를 발견하면 알려주는 것 실행자체가 안됨
3. 런타임 에러
실행 시 발생되는 오류로 프로그램 종료
에러 : 코드에 의해서 수습될 수 없는 심각한 오류 ex)OutOfMemoryError
예외 : 코드에 의해서 수습된 수 있는 미약한 오류
4. 예외 처리
예외 발생에 대비한 코드를 작성하는 것
프로그램의 비정상 종료를 막고 실행상태 유지
5. 예외 클래스
Exception 클래스 : 사용자의 실수와 같은 외적인 요인에 의해 발생
- IOException : 입출력 예외
- ClassNotFoundException : 클래스를 못 찾을 때
RuntimeException 클래스 : 프로그래머의 실수로 발생하는 예외
- ArithmeticException : 산술계산예외
- ClassCastException : 형변환
- NullPointerException : null을 가지는 객체 참조를 사용할 때
- IndexOutOfBoundsException : 배열 범위 벗어날 때
ch 8-4~6 예외 처리하기, try-catch문의 흐름
1. try-catch문
예외가 발생하면 처리할 catch블록으로 이동
Exception이 선언된 catch블럭은 모든 예외처리되므로 마지막에 위치하는 것이 좋음
→ 위쪽에 해당하는 예외 catch블럭이 있으면 실행 안됨
try {
// 예외가 발생할 가능성이 있는 문장
} catch (Exception e) {
// Exception 발생시 처리 문장
}
ch 8-7~8 printStackTrace(), 멀티 catch블럭
1. 예외발생 흐름
예외 발생 → 예외 객체 생성(예외 정보, 메서드) → catch블럭 참조변수로 → 예외처리
참조변수는 유효범위는 해당 catch블럭
2. 예외 객체의 메서드
printStackTrace() : 예외 발생 당시 호출 스택에 있던 메서드 정보, 예외메세지 출력
getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메세지 반환
3. 멀티 catch블럭
내용이 같은 catch블럭 하나로 합침 JDK1.7부터
부모-자식 관계는 불가
두 예외 모두 가지고 있는 공통멤버만 사용가능
try {
...
// 멀티 catch블럭
} catch (ExecptionA | ExecptionB e) {
e.printStackTrace();
}
ch 8-9~10 예외 발생 시키기
1. 예외 발생 시키기
// 예외 객체 생성
Exception e = new Exception("예외 메세지");
// 예외 발생 시킴
throw e;
연산자 new사용해 예외 클래스 객체 생성 후 키워드 throw를 이용해 예외를 발생시킴
2. checked & unchecked 예외
checked
컴파일러가 예외처리 여부를 체크하기 때문에 예외처리 필수
Exception과 자손
unchecked
컴파일러가 예외 처리 여부 체크 안함 예외처리는 선택 사항
RuntimeException과 자손
ch 8-11~14 예외 선언하기, finally블럭
1. 예외를 처리하는 방법
① try-catch
② 예외 선언하기
③ 은폐(빈 catch블럭 생성)
2. 예외 선언하기
throws 키워드 이용 예외를 호출하는 쪽에 전달함
// throws 키워드 이용해 메서드에 예외 선언
void method() throws ExceptionA, ExceptionB, ... {
}
예외의 최고 조상인 Exception을 선언하면 모든 종류의 예외 발생 가능성이 있다는 의미
class Ex8_10 {
public static void main(String[] args) {
try {
File f = createFile(args[0]);
System.out.println( f.getName()+"파일이 성공적으로 생성되었습니다.");
} catch (Exception e) {
System.out.println(e.getMessage()+" 다시 입력해 주시기 바랍니다.");
}
}
static File createFile(String fileName) throws Exception {
if (fileName==null || fileName.equals(""))
throw new Exception("파일이름이 유효하지 않습니다.");
File f = new File(fileName); // File클래스의 객체를 만든다.
// File객체의 createNewFile메서드를 이용해 실제 파일을 생성한다.
f.createNewFile();
return f; // 생성된 객체의 참조를 반환한다.
}
}
/*
""입력시
args[0] = "" createFile메서드로 전달
createFile메서드의 if문 false로 Exception 객체 생성
throws Exception로 예외 선언해 main으로 예외 전달
예외를 전달 받은 main에 try-catch문에서 예외 처리
=>출력
파일이름이 유효하지 않습니다. 다시 입력해 주시기 바랍니다.
*/
3. finally 블럭
예외 발생 여부와 관계없이 수행되어야 하는 코드
try (
// 예외가 발생될 가능성이 있는 문장
} catch (Exception e) {
// 예외 발생시 수행될 문장
} finally {
// 예외가 발생하더라도 실행되어야 하는 문장
}
ch 8-15~17 사용자 정의 예외 만들기, 예외 되던지기
1. 사용자 정의 예외
직접 예외 클래스를 정의할 수 있음
Exception, RuntimeException 중 선택하여 상속을 통해 작성
class MyException extends Exception {
// MyException(생성자 예외메세지를 매개변수로 받는 생성자)
MyException(String msg){
// 조상인 Exception클래스의 생성자 호출
super(msg);
}
}
2. 예외 되던지기
예외를 처리한 후 다시 예외를 발생시키고 호출한 곳에서 다시 처리
호출한 메서드와 호출된 메서드 양쪽 모두 예외 처리
class Ex8_12 {
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("main메서드에서 예외가 처리되었습니다.");
}
}
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e; // 예외를 다시 발생시킴
}
}
}
/*
main에서 method1 호출
method1에서 예외 발생
catch문으로 예외 처리 후 다시 예외 발생
method의 throws Exception로 main으로 예외 전달
main의 catch문에서 예외 처리
=> 출력
method1메서드에서 예외가 처리되었습니다.
main메서드에서 예외가 처리되었습니다.
*/
ch 8-18 연결된 예외
1. 연결된 예외
한 예외가 다른 예외를 발생
// 원인 예외로 등록
Throwable initCause(Throwable cause)
// 원인 예외 반환
Throwable getCause()
여러 예외를 하나로 묶어서 다루기 위해 사용
checked 예외를 unchecked예외로 변경하려 할 때 사용