1. 예외처리(exception handling)

  • 컴파일 에러 : 컴파일 시에 발생하는 에러
  • 런타임 에러 : 실행 시에 발생하는 에러
  • 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것 

 

  • 에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
  • 예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

 

1.1. 예외 클래스의 계층구조

exception
    |
    |-IOException
    |-ClassNotFoundException
    |-...
    |-RuntimeException
            |
            |-ArithmeticException
            |-ClassCastException
            |-NullPointerException
            |-...
            |-IndexOutOfBoundsException

예외 클래스들은 두 개의 그룹을 나눠질 수 있음

  • RuntimeException클래스와 그 자손클래스들 
    • 프로그래머의 실수로 발생하는 예외
  • Exception클래스와 그 자손클래스들(RuntimeException과 그 자손들 제외)
    • 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외

 

1.2. 예외처리하기 - try-catch문

예외처리(exception handling)의 정의

프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것

 

예외처리의 목적

프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것

 

try {
	//예외가 발생할 가능성이 있는 문장들을 넣음
} catch (Exception1 e1) {
	//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적음
}
} catch (Exception2 e2) {
	//Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적음
}

 

1.3. try-catch문에서의 흐름

  • try블럭 내에서 예외가 발생한 경우
    • 1. 발생한 예외와 일치하는 catch블럭이 있는지 확인
    • 2-1. 일치하는 catch블럭을 찾게 되면, 그 catch블럭 내의 문장들을 수행하고, 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행
    • 2-2. 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못함
  • try블럭 내에서 예외가 발생하지 않은 경우
    • catch블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속함

 

 

1.4. 예외 발생시키기

//1. 먼저, 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든다
Exception e = new Exception("고의로 발생시켰음)

//2. 키워드 throw를 이용해서 예외를 발생시킴
throw e;

 

1.5. finally블럭

finally 블럭 : try-catch문과 함께 예외의 발생여부에 상관없이 실행되어야 할 코드들 포함시킬 목적으로 사용됨

try {
	//예외가 발생할 가능성이 있는 문장들을 넣음
} catch (Exception1 e1) {
	//예외 처리를 위한 문장들을 적음
} finally {
	//예외의 발생여부에 관계없이 항상 수행되어야 하는 문장들을 넣음
	//finally블럭은 try-catch문의 맨 마지막에 위치해야함
}

 

1.6. 자동 자원 반환 - try-with-resources문

사용했던 자원을 반환

입출력과 관련된 클래스를 사용할 때 유용

 

try {
    fis = new FileInputStream("score.dat");
    dis = new DataInputStream(fis);
    ...
} catch (IOException ie) {
    ie.printStactTrace();
} finally {
    dis.close(); //작업 중에 예외가 발생하더라도, dis가 닫히도록 finally블럭에 넣음
}

//좀 더 안전하게 사용
try {
    fis = new FileInputStream("score.dat");
    dis = new DataInputStream(fis);
    ...
} catch (IOException ie) {
    ie.printStactTrace();
} finally {
    try {
        if(dis != null)
            dis.close();
    } catch(IOException is) {
        ie.printStactTrace();
    }
}

//try-with-resources문 사용
try(fis = new FileInputStream("score.dat");
	dis = new DataInputStream(fis)) {
    while(true) {
    	score = dis.readInt();
        System.out.println(score);
        sum += score;
    }
} catch(EOFException e) {
	System.out.println("점수의 총합은 " + sum + "입니다");
} catch(IOException ie) {
	ie.printStactTrace();
}

try-with-resources문의 괄호()안에 객체를 생성하는 문장을 넣으면, 이 객체는 따로 close()를 호출하지 않아도 try블럭을 벗어나는 순간 자동적으로 close()가 호출

 

1.7. 예외 되던지기(exception re-throwing)

예외 되던지기 : 예외를 처리한 후에 인위적으로 다시 발생시키는 방법

 

예제

class ExceptionEx17 {
	public static void main(String[] args)
    {
    	try {
        	method1();
		} catch (Exception e) {
        	System.out.println("main 메서드에서 예외가 처리되었습니다");
        }
    }
    
    static void method1() throws Exception {
    	try {
        	throw new Exception();
        } catch (Exception e) {
        	System.out.println("method1 메서드에서 예외가 처리되었습니다");
            throw e; //다시 예외를 발생시킴
        }
    }
}

//결과
method1 메서드에서 예외가 처리되었습니다
main 메서드에서 예외가 처리되었습니다
복사했습니다!