티스토리 뷰
1. 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
- 예외처리 정의 : 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것
- 예외처리 목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것
try-catch
- try 블럭에서 에외가 발생한 경우,
- 발생한 예외와 일치하는 catch 블럭이 있는지 확인한다 (instanceof 의 연산으로 계산)
- 일치하는 catch 블럭을 찾으면 그 블럭 내의 문장들을 수행 후, try-catch 구문을 빠져나가서 그 다음문장을 수행한다, 일치하는 catch 블럭이 없으면 예외 처리되지 못한다
- try 블럭에서 예외가 발생하지 않은 경우
- catch블럭을 거치지 않고 try-catch 문을 빠져나가서 수행을 계속한다
- 발생한 예외의 종류와 일치하는 한개의 catch 블럭만 수행됨
- try 블럭, catch 블럭에 또 다른 try-catch 구문이 포함될 수 있음
- 첫 번째 검사에서 일치하는 catch 블럭을 찾으면 두 번째 catch 블럭은 검사하지 않음 -> catch문의 마지막에 Exception 타입을 선언 하면 어떤 종류의 예외가 발생하더라도 이 catch에 의해 처리될 수 있음
try {
// 예외 발생 가능성이 있는 구문
try {} catch(Exception e) {} // e 사용가능
} catch (Exception e) {
// Exception이 발생했을 경우, 이를 처리하는 구문
try {} catch(Exception e) {} // 에러 변수 e가 중복선언됨
} catch (Exception2 e2) {
// Exception2이 발생했을 경우, 이를 처리하는 구문
} catch (ExceptionN eN) {
// ExceptionN이 발생했을 경우, 이를 처리하는 구문
}
- printStackTrace() : 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력함
- getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻음
- | 로 연결된 클래스들의 공통 분모인 예외클래스에 선언된 멤버만 사용할 수 있음
try {
} catch(ExceptionA | ExceptionB e){
e.printStackTrace();
}
try {
} catch(ParentException | ChildException e){ // 에러, 조상과 자손의 관계가 있으면 컴파일에러
e.printStackTrace();
}
try {
...
} catch (ExceptionA | ExceptionB e) {
e.methodA() // 에러, ExceptionA에만 선언된 메서드는 호출 불가
if(e instanceof ExceptionA) {
ExceptionA e1 = (ExceptionA)e;
e.methodA(); // 사용 가능
} else {
// instanceof ExceptionB
}
}
throw
- throw 사용하여 고의로 예외를 발생 시킬수 있음
- new로 발생시키려는 예외클래스의 객체를 만듬
- throw를 이용하여 예외를 발생
- 생성시 String을 넣으면 getMessage() 메서드로 얻을 수 있음
Exception e = new Exception("고의로 발생시켰음");
throw e;
// 위 두줄을 한줄로
throw new Exception("고의로 발생시켰음");
throws
- throws : 메서드 내에서 발생할 수 있는 예외를 적어줄 수 있음, 이에 대한 처리를 하도록 강요
- , (쉼표) 로 구분하여 여러개를 적어 줄 수 있음
void method() throws Exception1, Exception2, ... ExceptionN {
// ....
}
- throws에 명시하는 것은 예외를 처리하는 것이 아니라 자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것
class ExceptionEx12 {
public static void main(String args[]) throws Exception {
method1();
}
static void method1() throws Exception {
method2();
}
static void method2() thorows Exception {
throw new Exception();
}
}
// 실행 결과
java.lang.Exception
at ExceptionEx12.method2(ExceptionEx12.java:11)
at ExceptionEx12.method1(ExceptionEx12.java:7)
at ExceptionEx12.main(ExceptionEx12.java:3)
- 예외가 발생했을 때 모두 3개의 메서드가 호출 스택에 있음 main, method1, method2
- 예외가 발생한 곳은 method2()
- main 메서드가 method1()을 method1() 메서드가 method2()를 호출함
finally
- try-catch 문과 함께 예외 발생 여부와 상관없이 실행되어야할 코드를 포함
try {
// 예외 발생 가능성이 있는 구문
} catch (Exception1 e1) {
// 예외처리를 위한 문장
} finally {
// 예외 발생 여부와 관계없이항상 수행되어야하는 문장
// try-catch문 마지막에 작성
}
class FinallyTest {
public static void main(String args[]) {
FinallyTest.method1();
System.out.pringln("종료");
}
static void method1(){
try {
System.out.println("method1() 실행");
return;
} catch (Exception e) {
//e.printStackTrace();
} finally {
System.out.println("finally 실행");
}
}
}
// 실행결과
method1() 실행
finally 실행
종료
2. 자바가 제공하는 예외 계층 구조
- Exception 클래스들 (Runtime Exception 제외) : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
- FileNotFoundException, ClassNotFoundException, DataFormatException 등
- RuntimeException 클래스들 : 프로그래머의 실수로 발생하는 예외
- ArrayIndexOutofBoundsException, NullPointerException, ClassCastException, ArithmeticException 등
- 모든 예외 클래스는 Exception클래스의 자손이므로, catch 블럭에 Exception을 선언하면 어떤 종류의 예외가 발생하더라도 이 catch 블럭에서 처리됨
3. Exception과 Error의 차이는?
- 에러와 예외는 모두 런타임 시 발생하는 오류임
- 에러(error) : 프로그램 코드에 의해서 수습 될 수 없는 심각한 오류, 메모리 부족(OutOfMemoryError)이나 스택오버플로우(StackOverflowError) 등
- 예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류, 발생하더라도 프로그래머가 이에 대비한 적절한 코드를 작성하여 프로그램의 비정살 종료를 막을 수 있음
4. RuntimeException과 RE가 아닌 것의 차이는?
- 런타임 에러 : 실행 시에 발생하는 에러
- 실행 중 동작을 멈춘 상태로 오랜 시간 지속되거나, 갑자기 프로그램이 실행을 멈추고 종료되는 경우
- 에러, 예외(exception) 두가지로 구분됨
- 컴파일 에러 : 컴파일 시에 발생하는 에러
- 소스코드 오타, 잘못된 구문, 자료형 체크
- 논리적 에러 : 실행은 되지만 의도와 다르게 동작하는 것
5. 커스텀한 예외 만드는 방법
- 가능하면 기존의 예외 클래스를 활용
class MyException extends Exception {
MyException(String msg) {
super(msg); // 조상인 Exception 클래스의 생성자를 호출함
}
}
class MyException extends Exception {
private final int ERR_CODE;
MyException (String msg, int errCode) {
super(msg);
ERR_CODE = errCode;
}
MyException(String msg) {
this(msg, 100);
}
public int getErrCode(){
return ERR_CODE;
}
}
class MyException extends Exception {
private final int ERR_CODE;
MyException (String msg, int errCode) {
super(msg);
ERR_CODE = errCode;
}
MyException(String msg) {
this(msg, 100);
}
public int getErrCode(){
return ERR_CODE;
}
}
class NewExceptionTest {
public static void main(String args[]){
try{
start();
} catch(MyException e) {
System.out.println(e.getMessage());
System.out.println(e.getErrCode());
} finally {
System.out.println("finally 구문");
}
}
static void start() throws MyException{
throw new MyException("MyException 예외 생성", 200);
}
}
출처
자바의 정석, 남궁 성 지음
'개발 > Java Study' 카테고리의 다른 글
11주차 : Enum (0) | 2021.02.21 |
---|---|
10주차 : 멀티쓰레드 프로그래밍 (0) | 2021.02.20 |
8주차 : 인터페이스 (0) | 2021.02.15 |
7주차 : 패키지 (0) | 2021.02.13 |
6주차 : 상속 (0) | 2021.02.13 |