-
오류는 시스템상으로 나타나기때문에 개발자가 어찌할 수 없다. 반면에 예외는 내가 구현한 로직에서 문제가 생긴것이다.
프로그램 실행 중 발생하는 에러인 Exception은
(1) 연산자에 의해 발생
(2) 메서드 호출에 의해 발생
(3) throw문을 이용하여 인위적으로 발생
예외는
(1) try catch문으로 처리되거나
(2) throw로 던질 수 가 있는데
던져진 예외는
(1) 메서드 호출문이 속하는 try catch문에 의해 처리되거나
(2) 다시 던져질 수도 있으며
끝까지 처리가 안되면 main 메서드 밖으로 던져지게 되고 자바 가상 기계가 예외를 잡아 에러 메시지를 출력하고 프로그램을 종료시킴
익셉션 객체와 익셉션 클래스
자바에서 익셉션은 객체로 만들어지기 때문에, catch절에서도 해당 객체를 대입 할 수 있는 변수로 잡아야 함. ( 위 빨간색 박스 참조 )
new로 선언한 예외 객체는 Exception 타입의 변수를 이용해서 잡는 것을 볼 수 있다.
자바에서는 익셉션을 만들 수 있는 클래스를 exception class라고 한다. java.lang 패키지에 있는 throwable 클래스와 이 클래스를 상속 받는 클래스들만이 exception class가 될 수 있다.
https://docs.oracle.com/javase/7/docs/api/ 자바 API 싸이트에서 throwable class를 검색하면 Exception과 Error라는 서브 클래스를 가지고 있으며 이들은 또 무수한 서브 클래스를 가지고 있는 것을 알 수 있다.
Exception class는 비교적 덜 심각한 익셉션을 표현하고 Eroor클래스는 상대적으로 심각한 익셉션을 표현한다. 에러는 발생 위치 파악, 복구가 어렵기 때문에 try catch문으로 처리 하기 어렵고 Exception class만 try catch문으로 처리가 가능하다.
try catch문으로 꼭 체크 해야하는 exception을 checked exception 그렇지 않아도 되는 것을unchecked exception이라고 한다. Excpetion sub class인 RuntimeException class가 이를 나누는 기준이 된다. RunntimeException과 그 sub Class들은 unchecked exception이다.
그래서 checked Exception은 컴파일단계에 바로 밝혀지고 Unchecked Exception은 실행단계에 확인 할 수 있다.
책에서는 아래와 같이 두 예제를 두고 두번째 예제는 checked Exception(checked)를 발생시키고 첫번째 코드는 ArithmeticException(unchecked)를 발생시켰다.
두번째는 컴파일 예제가 존재하고 첫번째는 컴파일 예제가 존재하지 않는다. 그러므로 두번째 예제는 try catch문을 사용하여서 처리하여야한다.
[1]
[2]
<<수정>>
메서드 밖으로 던져지는 경우에도 동일하다.
동일한 이유로 unchecked Exception을 던져보아도 이는 컴파일상에서 아~무런 문제가 없다.
익셉션 클래스의 사용방법
익셉션 클래스는 상속 관계를 갖기 때문에 모든 익셉션 객체에 대해 공통된 메서드를 호출할 수 있다. 또한 여러 타입의 익셉션을 catch문 하나로 한방에 처리할 수 있다.
Throwable 클래스에서 자주 쓰이는 메서드인 getMessage와 printStackTrace 메서드를 살펴보자.
getMessage 메서드는 다음과 같이 사용할 수 있다. 익셉션 객체가 가지고 있는 에러 메세지를 리턴해준다.
*"/by zero" 가 자바 가상 기계가 ArithmeticException에 자동으로 설정하는 에러 메세지
우리가 직접 생성하는 throw new Exception은 파라미터로 넘겨준 값을 출력한다. 아무것도 전달하지 않으면 null을 출력한다.
printStackTrace 메서드는 익셉션이 발생한 경로를 추적하여 더 상세한 익셉션의 정보를 알 수 있다. 아래 사진을 보면 어디서 에러가 발생했는지를 알 수 있다. 책에서는 이렇게 주절주절 콘솔창에 올라오면 보기 싫으니까 디버깅할때만 쓰라고 적혀있다. 완성단계에는 쓰지 말것.
익셉션 파라미터는 익셉션 객체를 받는 데 사용되기 때문에 익셉션 객체를 대입할 수 있는 타입으로 선언해야 한다.
받는 역할 뿐이 아니라 Catch절이 처리할 서브 클래스의 익셉션을 포함한 익셉션 객체를 골라서 잡아내는 역할까지도 한다. 아래 코드를 보면 FileNotFound는 IOException의 서브 클래스이기때문에 익셉션을 캐치할 수 있는것을 알 수 있다.
아래와 같이 Exception을 2개 처리하면 순서대로 처리하기떄문에 FileNotFoundException의 결과만 출력된다.
( 처리해야 하는 익셉션이 사라졌기때문에 IOException에서는 할 일이 없다.)
그런데! 이 둘의(Filenotfound,IoException) 순서를 바꾸면 컴파일도 안된다. IO 익셉션이 FileNotFound가 할일까지 모조리 해버리기 떄문...
자바 7 부터는 이런식으로 동시에 에러를 나열할 수 있다 ( 단, 서브 클래스 익셉션이랑 같이 두면 X )
익셉션 클래스의 선언 방법
특별히 상속받아야 할 클래스가 있는게 아니라면 Exception class를 바로 상속받아서 선언한다. 되도록 이름 끝에 Exception을 붙이면 좋다. super class의 생성자를 호출하여 에러 메시지를 저장한다.
사용 예시는 다음과 같다.
자 책에 안나와있는 내용(다른 챕터에 있을수도 있지만..;;)
1) System.err.println
- 우리가 흔히 쓰던 System.out.println 은 표준 출력을 인쇄하고 err는 표준 오류를 인쇄한다.
- 둘다 그냥 기본 콘솔에서 결과는 같지만 스트림을 다시 구성할 수 있다. 예를들어 out은 콘솔에 계속 인쇄하지만 err는 파일에 기록
할 수 있다.
- Eclipse같은 IDE는 err는 빨간색으로 표시하고 out은 검은색으로 표시한다.
더 찾아보니 그냥 구분하기 위해서 나누는 경우가 많다고 한다.
2) Exception의 생성자 마지막예시에 super()를 사용한다. 따라가보자
Exception 클래스 역시 부모의 생성자를 사용하고 있다. Throwable의 생성자를 살펴보면 아래와 같다.
message는 오류에 대한 상세 메시지이며 cause는 오류 발생의 원인이 되는 상세 예외를 생성자로 넘긴다. 아래 API에서 퍼온 더 자세한 내용이 있다.
3) http://www.nextree.co.kr/p3239/ 이 블로그에서 재밌는 단어를 봤는데 예외 처리 방법에는 아래와 같이 3단계로 이루어진다고 한다.
1) 예외 복구
핵심은 예외가 발생해도 프로그램이 정상적인 흐름으로 진행되는 것으로 발생하면 다른 작업으로 흐를 수 있도록 유도하면 된다고 한다. try catch문 이용
2) 예외처리 회피
public void className() throws Exception{
이렇게 밖으로 던져버리는 것이다. 예전에 수업들을 때도 많이 들었지만 가급적 절대 하면 안되는 행동중 하나라 한다.
3) 예외 전환
예외가 발생할 때 잡아서 다른 예외로 던져버리는 것이라한다. (오 좀특이하다) 호출한쪽에서 예외를 처리할 떄 좀 더 명확하게 인지할 수 있도록 하는 것이 목적
catch(SQLException){
throw DuplicateUserIdException()l}
그리고 이 블로그에서 추가적으로 Checked 익셉션과 Unchecked Exception의 차이중 추가한 것이 체크 익셉션은 예외가 발생했을시 트랜잭션이 롤백하지 않고 언체크는 롤백을 한다고 한다.
3) 예외를 발생시킬 수 있다
'2018년 > Java' 카테고리의 다른 글
[JAVA] 멀티 스레드 (0) 2018.03.19