13 예외처리
l 예외 처리
○ 프로그램 오류
○ 프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우
○ 발생시점에 따라 구분
n 컴파일 에러 : 컴파일 시에 발생하는 에러
n 런타임 에러 : 실행 시에 발생하는 에러
n 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것
○ 컴파일 에러
n 소스코드(*.java) –컴파일 -> 클래스 파일(*.class)
n 컴파일러가 기본적인 검사 수행하여 오류 알려줌
n 오류 수정하여 컴파일 마치면 클래스파일 생성되고 실행할 수 있음
○ 런타임 에러
n 실행 도중 발생할 잠재적 오류까지 컴파일러가 검사할 수 없음
n 프로그램의 실행 도중 발생할 수 있는 모든 경우의 수 고려해 대비
n 에러와 예외 두 개가 있음
u 에러 : 메모리 부족이나 스택오버플로우 같이 일단 발생하면 복구할 수 없는 심각한 오류코드에 의해 수습 불가능
u 예외 : 발생하더라도 수습될 수 있는 비교적 덜 심각한 오류코드에 의해 수습 가능
n 예외는 적절한 코드로 비정상 종료 막을 수 있음
○ 예외 클래스의 계층 구조
n Exception 클래스와 그 자손들
u 외부의 영향으로 발생할 수 있는 것들
u 프로그램의 사용자들의 동작에 의해 발생하는 경우가 많음
u FileNotFoundException, DataFormatException 같은 것들
n RuntimeException 클래스와 그 자손들
u 프로그래머의 실수에 의해 발생 -> 자바의 프로그래밍 요소와 관련
u IndexOutBoundsException, NullPointerException, ClassCastException, ArithmeticException
l 예외 처리하기 try – catch 문
○ 예외처리 : 프로그램 실행 시 발생할 수 있는 예외 상황에 대한 대비 코드 짜는 것
○ try-catch문
n 하나의 try블록에 여러 종류의 예외 처리할 수 있도록 하나 이상의 catch블록 올 수 있음
n 예외 종류랑 일치하는 catch문만 실행되고 나머지는 패스
n 일치하는 예외가 없으면 예외 처리 되지 않음
try{
//예외가 발생할 가능성 있는 문장 넣기
}catch(Exception1 e1){
// Exception1 발생 했을 경우, 이를 처리하기 위한 문장 넣기
}catch(Exception2 e2){
// Exception2 발생 했을 경우, 이를 처리하기 위한 문장 넣기
} catch(ExceptionN eN){
// ExceptionN 발생 했을 경우, 이를 처리하기 위한 문장 넣기
}
// 참조변수도 잘 바꿔줘야 함
○ try-catch문에서의 흐름
n try블록에서 예외 발생했을 경우
(1) 발생한 예외가 일치하는 catch블럭 있는지 확인함
(2) 일치하는 catch블럭 찾으면 catch블럭 내 문장 수행 후 전체 try-catch문 빠져나가 다음 문장 실행
(3) 일치하는 catch블럭 못 찾으면 예외 처리 안됨
n try블록에서 예외 발생하지 않았을 경우
(1) catch블럭 거치지 않고 전체 try-catch문 빠져나가서 수행 계속함
n try 블록에서 예외 발생하면 예외 발생 위치 이후 try블럭 안에 있는 문장 실행 한하므로 코드 범위 잘 선택해야 함
○ finally블럭
n try-catch문에서 예외 발생 여부에 상관 없이 실행되어야 할 코드
try{
// 예외 발생할 가능성 있는 문장들
}catch(Exception1 e1){
// 예외 처리 문장
}finally(
// 예외 발생 여부에 상관없이 항상 수행되어야 하는 문장
// try-catch문 맨 마지막에 위치
)
n try 블록이나 catch 블록 문장 수행 중에 return문 만나도 finally블럭 문장 수행됨
○ 예외 발생과 catch블럭
n catch문 안에 괄호 속 예외와 try문에서 발생한 예외를 instanceof해서 catch블럭 찾음
n Exception 클래스 타입은 모든 예외의 조상이므로 catch에 선언 안된 것은 이 블록으로 옴먼저 만나는 catch문이 일치하면 뒤에 catch문 실행 안되므로 젤 큰 예외 클래스는 마지막에 넣자
n printStackTrace() & getMessage()
u printStackTrace() : 예외 발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지 화면에 출력함
u getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지 얻음
u catch구문 괄호 안에 선언한 예외 참조변수로 메서드에 접근 가능
n 멀티 catch블럭
u ‘ | ‘ 기호 이용해 한 catch문에 다중 예외 넣음
u try {…} catch(Exception1 e1 | Exception2 e2){ … }
u 멀티 catch블록의 ‘ | ‘ 기호로 연결된 예외 클래스가 조상자식 관계면 컴파일 에러!조상만 선언해도 되는 것이니까
l 예외 발생시키기
○ 키워드 throw
n 프로그래머가 고의로 예외 발생 시키기
(1) 연산자 new를 이용해 발생시키려는 예외 클래스 객체 만들기
(2) 키워드 throw를 이용해 예외 발생
n Exception 인스턴스 생성할 때 생성자에 String 넣어주면 이 String이 Exception 인스턴스 메세지로 저장됨 -> getMessage()로 가져올 수 있음
○ RuntimeException과 그 자손 클래스
n 프로그래머가 실수해서 발생하는 것! -> 따로 굳이 예외 처리 안해도 됨
n 컴파일러가 예외처리 강제하지 않음 -> unchecked 예외
n 컴파일러가 예외 처리 확인하는 Exception 클래스들은 checked 예외
l 메서드에 예외 선언
○ 메서드 선언부에 throws 사용해 메서드 내에서 발생할 수 있는 예외 적어줌
n 이 예외 뿐 아니라 자손 타입 예외도 발생할 수 있음
n 메서드 사용 시 메서드 선언부를 보고 어떤 예외들이 처리되어야 하는지 명시하는 역할
○ 예외 처리 떠맡기기
n 메서드 사용하는 쪽에 이에 대한 처리를 강요하는 용도로 함
n 자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 용도임
n 어느 한 곳에서 반드시 try-catch로 예외처리 해 주어야 함
l 자동 자원 반환 –try-with-resources문
○ JDK 1.7부터 등장한 입출력 관련 클래스랑 사용하면 좋은 구문
n 입출력에 사용되는 클래스 중 사용한 후 꼭 닫아줘야 하는 것들을 닫아줌
n 자원 반환 해줘야 하는 것을 자원 반환해 줌
○ try-catch-finally 개선한 구문
n finally 구문에서 try-catch문 넣어서 자원 반환하면 코드 복잡함
n try 블록과 finally 블록 모두 예외 발생하면 try 블록 예외는 무시됨
n 이런 것들을 개선함
○ try-with-resources
n try문의 관호에 객체 생성하는 문장 넣어주면 이 객체는 따로 close() 호출 안 해도 try블럭 벗어나면 자동으로 close() 호출함
n AutoCloseale 인터페이스 구현한 객체를 자동으로 close() 호출할 수 있음
n 괄호 안에 두 문장 이상 넣을 경우 ‘ ; ‘로 구분
try(FileInputStream fis = new FileinputStream(“score.dat”) ;
DataInputStream dis = new DataInputStream(fis)){
….
}catch(Exception1 e1){
}
○ 억제된 예외
n 두 예외가 동시에 발생할 수 없음
è 실제 발생한 예외와 억제된 예외로 두 예외를 다룸
è 억제된 예외에 대한 정보는 실제 발생한 예외에 저장됨
n 억제된 예외와 관련된 메서드
u void addSuppressed(Throwable exception) : 억제된 예외 추가
u Throwable[ ] getSuppressed() : 억제된 에외(배열) 반환
l 사용자 정의 예외 만들기
○ Exception클래스 상속받아서 나의 예외 클래스 만들기 -> checked 예외가 되는 거지
n Exception class는 String 받아 메시지 저장 가능 -> String 받는 생성자 추가해줘야 됨
○ RuntimeException 클래스 상속받아 만들면 unchecked 예외가 됨
l 예외 되던지기 (exception re-throwing)
○ 한 메서드에서 발생한 예외가 여럿인 경우 -> 메서드 자신과 사용자 둘에서 양쪽에서 나눠 처리
n 몇 개는 try-catch문으로 메서드 내에서 자체로 처리
n 나머지는 선언부에 지정하여 호출된 메서드에서 처리
○ 자신이 예외를 처리한 후 인위적으로 다시 발생시켜 호출 메서드에서 처리하도록 함
n try-catch문을 사용해서 예외 처리 해주고 메서드 선언부에 발생할 예외를 throws에 지정해줌
n 반환값 있는 return문의 경우
u catch블록에도 return으로 반환값 써줄 수 있음
u catch문에서 예외 되던지기 해서 호출한 메서드로 예외 전달하면 return문 없어도 됨
n finally 블록 내에서도 return문 사용할 수 있음! 결국 finally return문 값이 반환됨
l 연결된 예외(chained exception)
○ 한 예외가 다른 예외 발생시키게 하는 것
n 원인 예외가 다른 예외를 발생시킴
n 예외를 하나의 큰 분류 예외로 묶어 다루되, 조상관계로 만들지 않는 방법
n checked 예외를 unchecked 예외로 바꿀 때도 씀
○ initCause()
n Throwable 클래스에 정의되어 있는 메서드들
□ Throwable initCause() (Throwable cause) : 지정한 예외를 원인 예외로 등록
□ Throwable getCause() : 원인 예외를 반환
■ 예외 생성한 뒤에 initCause 예외를 다른 예외의 원인 예외로 등록 후 throw로 던짐
■ 예외를 큰 분류로 묶어 다룰 수 있음
○ RuntimeException(Throwable cause)
■ 원인 예외를 등록하는 생성자
■ checked 예외를 unchecked 예외로 바꾸어 예외 처리를 선택적으로 함
■ RuntimeException으로 Exception 예외를 감싸는 것
'JAVA > 이론' 카테고리의 다른 글
[java][이론]014 컬렉션 프레임웍_List (0) | 2020.08.28 |
---|---|
[java][이론]014 컬렉션 프레임웍_개괄 (0) | 2020.08.28 |
[java][이론] 012 추상클래스와 인터페이스 (0) | 2020.08.12 |
[java][이론] 011 다형성 (0) | 2020.08.06 |
[java][이론] 010 제어자 (0) | 2020.07.08 |