예외 발생시키기
키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있다.
try {
// Exception e = new Exception("예외를 발생시킴");
// throw e;
throw new Exception("예외를 발생시킴"); // 메시지 지정
} catch (Exception e) {
e.printStackTrace();
}
만일 예외처리가 되어있어야 할 곳에 처리가 되어있지 않으면 컴파일 조차 실행되지 않을 수 있다.
RuntimeException 같은 경우는 예외 처리를 하지 않아도 컴파일이 가능하다.
throw new Exception(); // 컴파일 에러 발생
throw new RuntimeException(); // 컴파일 에러가 발생하지 않음
예외 처리하기
try-catch문에는 try블럭과 catch블럭이 구현되는데 try블럭에는 예외가 발생할 가능성이 있는 문장들이 들어가고 catch블럭에는 예외처리할 Exception 클래스를 받아 해당 Exception이 발생하였을때, 이를 처리하기 위한 문장들이 들어간다.
class TryCatchEx {
public static void main(String[] args) {
try {
// 예외가 발생할 가능성이 있는 문장들
} catch (Exception e) {
// Exception이 발생했을때, 이를 처리하기 위한 문장들
try { } catch (Exception e2) { } // 예외처리 안에 예외처리가 되었을땐 매개변수명을 다르게 정의
}
}
}
try-catch문에서의 흐름
try블럭 내에서 예외가 발생한 경우
- 발생한 예외와 일치하는 catch블럭이 있는지 확인
- 일치하는 catch블럭을 찾게 되면, 내부 문장들을 수행하고 try-catch문을 빠져나가서 다음 문장을 실행 일치하는 catch블럭이 없는 경우 예외는 처리되지 않는다.
System.out.print(1);
System.out.print(2);
try {
System.out.print(3);
System.out.print(0/0); // 에러발생, 0으로 나눌수 없다.
System.out.print(4); // try블럭에 에러발생 후 코드는 실행되지 않는다.
} catch (ArithmeticException e) {
System.out.print(5);
}
System.out.print(6);
// 결과 : 12356
try블럭 내에서 예외가 발생하지 않은 경우
- catch블럭을 거치지 않고 전체 try-catch문을 빠져나가 수행을 계속한다.
System.out.print(1);
System.out.print(2);
try {
System.out.print(3);
} catch (Exception e) {
System.out.print(4);
}
System.out.print(5);
// 결과 : 1235
예외의 발생과 catch블럭
catch블럭에 괄호()내에는 처리하고자 하는 예외와 같은 타입의 참조변수를 하나 선언해야 한다.
만약 try블럭에서 예외가 발생한다면 해당 예외가 참조변수로 선언된 catch문을 instanceof 연산자 사용해 위쪽부터 찾는다.
해당 예외가 참조변수로 선언된 catch문을 찾은경우 예외가 처리되지만, 해당 예외가 선언되지 않은 경우는 예외처리가 되지 않는다.
모든 예외 클래스는 Exception의 자손이므로, 참조변수로 Exception클래스를 선언할 경우 모든 예외에 대한 처리가 된다.
System.out.print(1);
System.out.print(2);
try {
System.out.print(3);
System.out.print(0/0); // 에러발생, 0으로 나눌수 없다. ArithmeticException 발생
System.out.print(4); // try블럭에 에러발생 후 코드는 실행되지 않는다.
} catch (Exception e) { // 모든 예외 처리 가능
System.out.print(5);
}
System.out.print(6);
// 결과 : 12356
printStackTrace()와 getMessage()
예외가 발생했을 때 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있으며, getMessage()와 printStackTrace()를 통해서 이 정보들을 얻을 수 있다.
printStackTrace()
예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력
getMessage()
발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
System.out.print(1);
System.out.print(2);
try {
System.out.print(3);
System.out.print(0/0); // 에러발생, 0으로 나눌수 없다. ArithmeticException 발생
System.out.print(4); // try블럭에 에러발생 후 코드는 실행되지 않는다.
} catch (ArithmeticException e) {
e.printStackTrace();
System.out.println("예외메시지 : " + e.getMessage());
}
System.out.print(6);
// 결과
// 123
// java.lang.ArithmeticException: ....
// 예외메시지 : / by zero
// 6
try-catch-finally문
finally블럭은 try-catch문과 함께 예외의 발생여부에 상관없이 실행되어야 할 코드를 포함시킬 목적으로 사용된다.
try-catch-finally의 순서로 구성된다.
예외가 발생한 경우는 try → catch → finally
예외가 발생하지 않은 경우 try → finally
try {
System.out.println("try");
return;
} catch (Exception e) {
System.out.println("catch");
} finally { // 예외에 발생여부와 관계 없이 항상 수행되어야 하는 문장
System.out.println("finally");
}
// 결과
// try
// finally
자동 자원 반환 try-with-resource문
JDK1.7부터 try-with-resource문이라는 try-catch문의 변형이 새로 추가되었다.
주로 입출력(I/O)과 관련된 클래스를 사용할때 유용하다.
try블럭 참조변수에 인스턴스를 생성해주게 되면 try문을 빠져나갈때 자동적으로 close가 호출된다.
자동으로 close()가 호출될 수 있으려면, 클래스가 AutoCloseable이라는 인터페이스(Interface)를 구현한 것이어야만 한다.
// AutoCloseable interface
public interface AutoCloseable {
void close() throws Exception;
}
// try-with-resource문을 사용하지 않았을때
try {
fis = new FileInputStream("score.dat");
dis = new DataInputStream(fis);
...
} catch (IOException ie) {
ie.printStackTrace();
} finally { // 예외 발생에 상관없이 DataInputStream을 닫아준다.
try {
dis.close(); // 예외가 발생할 수 있어 try-catch문을 한번 더 사용한다.
} catch (IOException ie2) {
ie.printStackTrace();
}
}
// try-with-resource문을 사용할 때
try (fis = new FileInputStream("score.dat"); // 여러개의 문장일 경우 ;로 구분
dis = new DataInputStream(fis)) {
while(true) {
score = dis.readInf();
System.out.println(score);
sum += score;
}
} catch (EOFException ee) {
System.out.println("점수의 총합은 " + sum + "입니다.");
} catch (IOException ie) {
ie.printStackTrace();
}
'Java' 카테고리의 다른 글
예외 되던지기(exception re-throwing) (0) | 2021.09.27 |
---|---|
사용자 정의 예외(Exception) 만들기 (0) | 2021.09.27 |
메서드(Method)에 예외(Exception) 선언하기 (0) | 2021.09.27 |
예외처리(Exception handling) (0) | 2021.09.20 |
내부 클래스(Inner class) (0) | 2021.09.20 |