이 글은 유튜브 '자바의 정석 - 기초편'을 보고 정리한 글입니다.
📂content
1. 예외 발생시키기
1. 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음
Exception e = new Exception("고의로 발생시켰음");
2. 키워드 throw를 이용해서 예외를 발생시킨다.
throw e;
⍟실습
Ex8_6
class Ex8_6 {
public static void main(String args[]) {
try {
Exception e = new Exception("고의로 발생시켰음.");
throw e; // 예외를 발생시킴
// throw new Exception("고의로 발생시켰음.");
} catch (Exception e) {
System.out.println("에러 메시지 : " + e.getMessage());
e.printStackTrace();
}
System.out.println("프로그램이 정상 종료되었음.");
}
}
결과
에러 메시지 : 고의로 발생시켰음
java.lang.Exception: 고의로 발생시켰음.
at Ex8_6.main(Ex8_6.java:4)
프로그램이 정상 종료되었음.
2. checked예외, unchecked예외
- checked 예외 => Exception과 그 자손
컴파일러가 예외 처리 여부를 체크(예외 처리 필수)
- unchecked 예외 => RunTimeException과 그 자손
컴파일러가 예외 처리 여부를 체크 안 함(예외 처리 선택)
=> try-catch를 안 해도 컴파일이 된다.
⍟실습
Ex8_7
class Ex8_7 {
public static void main(String[] args) {
throw new Exception(); // Exception을 고의로 발생시킨다
}
}
결과
Ex8_8
class Ex8_8 {
public static void main(String[] args) {
throw new RuntimeException(); // RuntimeExceptionÀ» °íÀÇ·Î ¹ß»ý½ÃŲ´Ù.
}
}
결과
try-catch문이 없는데도 위 코드를 돌리면 compile시 ok이다.
하지만 실제 실행시키면 프로그램이 죽는다.
Exception in thread "main" java.lang.RuntimeException at Ex8_8.main(Ex8_8.java:3)
RuntimeException을 예외처리 선택으로 안 하면 거의 모든 코드에 try~catch를 넣어야 하기 때문.
그래서 개발자가 주의해야 한다.
3. 메서드에 예외 선언하기
- 예외를 처리하는 방법
1. try - catch문 : 직접 처리
2. 예외 선언하기: 간접 처리(예외 떠넘기기)
예외 선언은 실제로 예외를 처리하는 것이 아니라 예외를 떠넘기(알리기)는 것이다.
- 메서드가 호출시 발생가능한 예외를 호출하는 쪽에 알리는 것
예외를 발생시키는 키워드 throw와 예외를 메서드에 선언할 때 쓰이는 throws를 잘 구별하기!
void method() throws Exception1, Exception2, ... ExceptionN {
// 메서드의 내용
}
throws는 해당 메서드를 호출하면 그러한 예외들이 발생할 수 있다는 것을 알려준다. 그러면 이 메서드를 호출한 곳에서는 저 예외를 처리하는 try-catch블록을 사용해야 한다. 아니면 자신도 떠넘긴다.
// method()에서 Exception과 그 자손 예외 발생 가능
void method() throws Exception {
// 메서드의 내용
}
오버라이딩 조건 3가지
1. 선언부 일치
2. 접근 제어자 좁게 x
3. 조상보다 많은 예외 선언 x
Throws 부분을 보면 IllegalMonitorStateException과 InterruptedException을 발생시킨다는 것을 알 수 있다.
그렇다면 이 메소드를 사용할 때, 이 예외가 발생할 수 있으므로 처리를 해주어야 한다.
그런데 왜 throws에는 InterruptedException에만 있나?
IllegalMonitorStateException는 RuntimeException에 있어서 예외처리 선택이다.
그런데 InterruptedException은 Exception에 있다. 그래서 예외처리 필수이다.
throws에는 필수 처리 예외만 적는다. 사실 둘 다 적어도 상관은 없지만 안 적는 것이 정석이다.
⍟실습
Ex8_9
class Ex8_9 {
public static void main(String[] args) throws Exception {
method1(); // 같은 클래스내의 static멤버이므로 객체생성없이 직접 호출가능.
} // main메서드의 끝
static void method1() throws Exception {
method2();
} // method1의 끝
static void method2() throws Exception {
throw new Exception();
} // method2의 끝
}
=> 예외를 처리하는 try-catch문이 없고 떠넘기다가 결국은 main 역시 비정상적으로 종료가 된다.
그리고 예외는 JVM에게 넘겨진다. 그래서 아래 사진은 JVM의 기본예외처리기로 출력한 것이다.
Ex8_10
import java.io.*;
class Ex8_10 {
public static void main(String[] args) {
try {
File f = createFile(args[0]);
System.out.println( f.getName()+"파일이 성공적으로 생성되었습니다.");
} catch (Exception e) {
System.out.println(e.getMessage()+" 다시 입력해 주시기 바랍니다.");
}
} // main메서드의 끝
static File createFile(String fileName) throws Exception {
if (fileName==null || fileName.equals(""))
throw new Exception("파일이름이 유효하지 않습니다.");
File f = new File(fileName); // File클래스의 객체를 만든다.
// File객체의 createNewFile메서드를 이용해서 실제 파일을 생성한다.
f.createNewFile();
return f; // 생성된 객체의 참조를 반환한다.
} // createFile메서드의 끝
} // 클래스의 끝
- args[0]이 test2.txt이다.
4. finally 블럭
- 예외 발생여부와 관계없이 수행되어야 하는 코드를 넣는다.
try {
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
// 예외처리를 위한 문장을 적는다.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야 하는 문장들을 넣는다.
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
- try블럭 안에 return문이 있어서 try블럭을 벗어나갈 때도 finally블럭이 실행된다.
출처
'🎥Back > 자바의 정석' 카테고리의 다른 글
[JAVA의 정석]hashCode(), toString() (0) | 2024.02.28 |
---|---|
[JAVA의 정석]사용자 정의 예외 만들기, 예외 되던지기 (0) | 2024.02.28 |
[JAVA의 정석] 프로그램오류. try-catch (0) | 2024.02.18 |
[JAVA의 정석]열거형 (0) | 2024.01.19 |
[JAVA의 정석]제네릭 형변환 (0) | 2024.01.19 |