예외처리
1.오류란.
프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생 한 것 (=에러)
1)오류의 종류
ㄱ)컴파일 에러 : 소스 상의 문법 에러, 소스 구문을 수정하여 해결
ㄴ)런타임 에러 : 입력 값이 틀렸거나, 배열의 인덱스 범위를 벗어났거나, 계산식의 오류 등
(if문으로 처리가 가능한 오류)
ㄷ)시스템 에러 : 컴퓨터 오작동으로 인한 에러(소스 구문으로 해결 불가)
2.예외(Exception)
소스 수정으로 해결가능한 오류(컴파일에러+런타임 에러)
-> 이런 예외 상황(예측 가능한 에러) 구문을 예외처리를 통해 해결
에러가 발생하면 그 아래에 소스코드들은 실행 되지 않는다.
1)예외 클래스 계층 구조
Throwable | -> | VirtualMachineError | ||
-> | Error | -> | ...... | |
-> | AWTError | |||
-> | RuntimeException ->.... | |||
-> | Exception | |||
-> | IOException ->... |
익셉션 최상위 throwable-> Exception/Erorr로 나뉘어짐
Error는 시스템 오류(소스 코드상으로는 해결 불가)
Exception은 ㄱ) UnChecked Exception(런타임에러 = IF로도 처리가능)
ㄴ) Checked Exception(TryCatch 혹은 Throws필요)
3.UnChecked Exception
Runtime Exception의 후손 클래스는 5가지 가있다.
1)Arithmatic Exception : 0으로 나누었을 경우 발생. (=if문으로 나누는 수가 0인지 검사)
2)ArrayIndexOutOfBounds Exception : 인덱스 값이 배열의 범위를 벗어났을 경우 발생
(= 배열.length를 통해 배열크기 확인)
3)NullPoint Exception : Null인 참조 변수로 객체 멤버 참조시도 시 발생(= 객체 사용전 참조변수가 Null인지 확인/
if문으로 Null일 경우 넘어가거나 정지)
4)ClassCast Exception : 형변환 사용 시 타입오류 (= Instanceof 연산자로 객체 타입 확인후 형변환)
5)NagativeArraySize Exception : 배열의 크기를 음수로 지정한 경우 발생 (= 배열의 크기는 음수가 될 수 없다.)
4.Checked Exception
try catch 혹은 throws 로 던저서 해결 하는 오류
1)Exception 확인
Java API 문서 참조시 해당 클래스의 생성자/메소드가 유발 할 수있는 에러 코드가 적혀있음 -> 해당 메소드를 사용 하려면 반드시 뒤에 명시된 예외클래스 처리 필요 혹은 Exception클래스로 처리
Ex) InputStream 의 경우 FileNotFound Exception 유발 가능
-> FileNotFoundException 혹은 IOException, Exception으로 처리 해야 한다.
2) 예외 처리 방법
ㄱ) Exception 처리를 호출한 메소드에게 위임
메소드 선언 시 throws Exception명 문을 추가 하여 호출한 상위 메소드에게 처리 위임
public void 메소드명 throws Exception명(){
//기능정의
}
-> 이 경우 타고 올라가다 main()까지 올라가서 처리 못하면 프로그램 비정상 종료
ㄴ) Exception이 발생한 곳에서 직접 처리
Try~catch문을 이용하여 처리
Try 에는 에러가 발생할 만한 코드가 들어가고, catch문에는 발생할 만한 Exception을 적을 수 있으며, 어느 오류인지 세세하게 알고 싶은 경우, 상속관계를 고려해 하위 클래스부터 상위 클래스로 적어 나간다.
Try{
//기능정의
}catch (Exception명 변수명 ){
//처리시 실행 문구
}catch(Exception명 변수명){
....
}[finally{
}]
(finally는 생략 가능)
finally문의 경우 catch문을 다 작성한 후 제일 마지막에 작성하는데, 이는 finally의 특성때문이다. finally문 오류가 발생 유무에 상관없이 실행되며, 상위에 return이 존재 해도 실행되기 때문이다.
(단 System.exit()는 프로그램이 꺼지기에 무시 하지 못한다.)
3)throw/ throws
ㄱ) throw : 예외를 강제로 발생하는 구문
throw new 익셉션명();
ㄴ)throws
예외가 일어나면 호출한 곳으로 던진다는 의미
접근제한자 자료형 메소드명() throws 익셉션명{
}
메인까지 가서 처리 못할 경우 프로그램 비정상 종료
메소드 C에서 강제적으로 오류를 내었다.
C를 가 호출되어 오류가 난 이후의 메소드들은 실행 되지 않았으며, 메인에서도 처리를 하지 못해 강제 종료된 모습이다.
빨간글씨의 첫번째 줄은 오류의 메세지
그 후는 전부 오류가 난 위치를 나타낸다.
만약 중간에 try catch문을 사용해서 예외처리를 했을 경우, 처리 후의 메소드 들에서는 정상 종료가 되었을 것이다.
4)try catch
Try 에는 에러가 발생할 만한 코드가 들어가고, catch문에는 발생할 만한 Exception을 적을 수 있으며, 어느 오류인지 세세하게 알고 싶은 경우, 상속관계를 고려해 하위 클래스부터 상위 클래스로 적어 나간다. finally의 경우 특별한 경우를 제외하고는 반드시 실행 되기 때문에 마지막에 작성한다.
Try{
//기능정의
}catch (Exception명 변수명 ){
//처리시 실행 문구
}catch(Exception명 변수명){
....
}[finally{
}]
(finally는 생략 가능)
이 처리시 실행문구는 일반적으로
변수명.getMessage(); < - 오류 메세지만 출력
변수명.printStackTrace(); <- 오류메세지와 오류 위치 출력
출력문구;
오류가 났을 시 실행할 메소드
등이 들어 갈 수 있다.
위의 오류를 main에서 Try catch 문으로 잡았을 경우이다.
try문안에 있는 tt.methodA(); 에서 오류가 발생해 그 아래 예외가 발생하지 않았다는 구문 실행전 catch문으로 들어가게 된다.
Exception 오류를 찾아가 실행 구문들을 작동시킨후 finally가 실행 되었다.
그리고 오류처리가 끝나고 마지막 프로그램 정상 종료까지 마친 모습이다.
만약 try문안에 후에 배울 I/O 구문이 들어갈시 무조건 실행되는 finally에서 입출력자원을 .close 해주며 이역시 finally 문 내에서 try catch를 해주어야 한다.
5) try with resource 구문
Java 7버전 에서 추가된 기능으로, try안에 작성된 입출력자원(도구)을 직접 close()를 통해 반납하지 않고 해당 구문이 종료 되었을 때 자동으로 반납하는 예외처리 구문이다.
--> finally에 작성되었던 close()처리를 생략한 구문이며, 자동으로 close되게 하는 구문
try (반납할 자원 정의
//입력객체
//출력객체
){
//기능정의
catch(Excption명 변수명){
//에러시 처리문구
}
4. 사용자 정의 익셉션
클래스에 Exception을 상속받아 예외를 처리하는 객체를 생성하며
매개변수 생성자에 메세지를 받아 super(메세지); 를 통하여 에러를 받았을 때 예외메세지로 던져주고 처리하는 클래스를 만든다.(에러를 강제적으로 만들어 넘겨줄 수있다)
checkAge()메소드는 18세 이하면 에러를 발생시켜 MyException으로 던진다(생성자에 의한 생성).
18세 이하일 경우 try문에서 에러가 발생하여 Catch문 중 MyException을 찾아가 생성된 메세지를 반환하여 출력메소드를 통해 출력한다.