[2017/2/19] Project Java: CH 8. 예외처리

CH 8. 예외 처리
1. 예외 처리
1.1. 프로그램 오류
-프로그램 에러: 프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우 이러한 결과를 초래하는 원인
-발생 시점에 따른 분류
● 컴파일 에러: 컴파일 시에 발생하는 에러
● 런타임 에러: 실행 시에 발생하는 에러
● 논리적 에러: 실행은 되지만, 의도와 다르게 동작하는 것
-소스코드(*.java)가 컴파일러에 의해 오타, 구문 등 체크된 후 클래스 파일(*.class) 생성됨.
-컴파일러에 의해 검사되지 못한 오류가 있을 경우 비정상적으로 종료되거나 잘못된 결과가 나옴.
-런타임 에러를 방지하기 위해서는 프로그램의 실행 도중 발생할 수 있는 모든 경우의 수를 고려하여 이에 대한 대비를 해야 함.
-실행 시 발생할 수 있는 오류
● 에러: 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
● 예외: 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

1.2. 예외 클래스의 계층구조
-Exception과 Error 클래스 역시 Object 클래스의 자손들이다.
-예외 클래스는 두 개의 그룹으로 나뉠 수 있다.
● RuntimeException 클래스와 그 자손 클래스들
● 프로그래머의 실수로 발생하는 예외
● 자바의 프로그래밍 요소들과 관계가 깊다.
● 벗어난 배열의 범위, 값이 null인 참조변수의 멤버 호출 등
● Exception 클래스와 그 자손 클래스들
● 사용자의 실수와 같이 외적인 요인에 의해 발생하는 예외

1.3. 예외 처리하기 – try – catch 문
-예외 처리의 정의: 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것.
-예외 처리의 목적: 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것.
-발생한 예외 처리 못하면 프로그램은 비정상적으로 종료
-처리되지 못한 예외는 JVM의 예외처리기가 받아서 원인을 화면에 출력한다.

try{
//예외가 발생할 가능성이 있는 문장들을 넣는다.
}catch(Exception1 e1){
//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
}catch(Exception2 e2){
//Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적는다. }
-하나의 try 불록에 하나 이상의 catch 불록을 넣을 수 있다.
-이 중 예외의 종류와 일치하는 단 한 개의 catch 불록만 수행된다.
-if문과 달리 try와 catch은 괄호 {}를 생략할 수 없다.

try{
try{ } catch (Exception e) { }
}catch(Exception e){
try{ } catch (Exception e2) { }
}

-try불록과 catch불록에 또 다른 try-catch문이 포함될 수 있다.
-catch 불록의 괄호 내에 선언된 변수는 catch 블록 내에서만 유효하기 때문에 모든 catch 블록에 하나의 참조변수 이름을 사용해도 된다.
-그러나 catch 블록 내에 또 다른 try – catch 문이 있을 경우 서로 구별해줘야 한다.

1.4. try – catch 문에서의 흐름
● 예외가 발생한 경우
1. 발생한 예외와 일치하는 catch 블록이 있는지 확인한다.
2. 일치하는 블록 있으면 그 catch 블록 내의 문장들을 수행한다. 이후 전체 try – catch 문을 빠져나감
● 예외가 발생하지 않은 경우
1. 전체 try – catch 문을 빠져나간다.

1.5. 예외의 발생과 catch 블록
-괄호() 내에는 처리하고자 하는 예외와 같은 타입의 참조변수 하나를 선언해야 한다.
-첫번째 catch블록부터 차례대로 내려가면서 예외클래스의 인스턴스에 instanceof연산자를 이용해서 검사.
-괄호 ()에 Exception 타입의 참조변수 선언하면 어떤 종류의 예외가 발생하더라도 처리됨.
-catch 마지막에 Exception 클래스 타입의 참조변수 선언한 catch 블록 선언하면 어떤 종류의 예외도 처리 가능.
-예외가 발생했을 때 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있음
● printStackTrace(): 예외발생 당시에 호출 스택에 있었던 메서드의 정보와 예외 메시지를 출력
● getMessage(): 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.

try{ } catch (Exception1 e){
e.printStackTrace();
System.out.println(e.getMessage());
}

-멀티 catch 블록: 여러 catch 블록을 | 기호 이용해서 하나의 catch 블록으로 합칠 수 있게 함

try {
//…
}catch (ExceptionA | ExceptionB e){
e.printStackTrace();
}

-|기호로 연결된 예외 클래스가 조상과 자손 관계라면 컴파일 에러 발생
-참조변수 e는 상수이므로 값을 변경할 수 없다.

1.6. 예외 발생시키기
-키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있다.
1. 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체 만들기
Exception e = new Exception(“고의로 발생시킴”);
2. 키워드 throw를 이용해서 예외를 발생시킴
throw e;

-Exception 인스턴스 생성할 때 생성자에 String 넣어주면 이 String이 Exception 인스턴스에 메시지로 저장된다.
-RuntimeException클래스와 그 자손 클래스의 예외는 프로그래머가 실수로 발생하는 것, 예외 처리 강제하지 않는다 –> unchecked 예외
-Exception클래스와 그 자손 클래스 –> checked 예외

1.7. 메서드에 예외 선언하기
-메서드 선언부에 키워드 throws 이용해서 메서드 내에서 발생할 수 있는 예외를 적어주면 된다.

void method() throws Exception1, Exception2 { … }

-Exception 클래스 선언하면 모든 종류의 예외가 발생할 가능성이 있다는 뜻.
-견고한 프로그램 코드를 작성할 수 있도록 도와주는 방법
-unchecked 예외는 보통 적지 않는다. 반드시 처리하지 않아도 되기 때문
-메서드에 throws 명시하는 것은 예외를 처리하는 것이 아닌 자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것.
-main까지 올라가고, 처리가 안 될 시 프로그램 전체가 종료된다.

1.8. finally 블록
-예외의 발생 여부와 상관없이 실행되어야 할 코드를 포함시키는 블록
-예외 발생시 try – catch – finally 순으로 실행
-try불록에서 return문이 실행되는 경우에도 finally 블록의 문장들이 먼저 실행된 후 현재 실행 중인 메서드를 종료한다.

1.9. 자동 자원 반환 – try – with – resources문
-입출력과 관련된 클래스 사용할 때 유용하다.
-사용한 후에 꼭 닫아줘야 하는 것들을 finally 블록에 넣을 때 close()가 예외를 발생시킬 경우 문제 발생 –> 복잡할뿐더러 try와 finally 모두에서 예외 발생할 경우 try 블록 예외 무시됨.

try(fis = new FileInputStream(“score.dat”);
dis = new DataInputStream(fis)) { } catch(EOFException e) { }

-괄호 안에 객체 생성하는 문장 넣으면 close() 호출하지 않아도 자동적으로 close()가 호출됨. 이후에 catch나 finally가 실행

1.10. 사용자정의 예외 만들기
-프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있다.
-가능하면 기존의 예외 클래스 활용하자.

class MyException extends Exception{
MyException (String msg) {
super (msg);
}
}

-요즘은 예외처리를 선택적으로 할 수 있도록 RuntimeException 상속하는 경우로 바뀌고 있음.

1.11. 예외 되던지기
-몇 개는 try – catch 문을 통해서 메서드 내에서 자체 처리, 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 함.
-메서드 선언부에 발생한 예외를 throws에 지정해줘야 함.

1.12. 연결된 예외
-한 예외가 다른 예외를 발생시킬 수도 있다.

try { } catch (SpaceException e) {
InstallException ie = new InstallException(“설치 중 예외 발생”); //예외 생성
ie.initCause(e); //InstallException의 원인 예외를 SpaceException으로 지정
throw ie; //InstallException을 발생시킴
}
-initCause()는 Exception클래스의 조상인 Throwable 클래스에 지정됨. 지정된 예외를 원인 예외로 지정하는 메서드.
-여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함
–> 조상으로 뭉쳐서 할 경우 실제로 발생한 예외가 어떤 것인지 알 수 없다.

댓글 남기기