이 글은 유튜브 '자바의 정석 - 기초편'을 보고 정리한 글입니다.
📂content
1. 프로그램 오류
- 컴파일 에러 (compile-time error) : 컴파일 할 때 발생하는 에러
- 런타임 에러 (runtime error) : 실행 할 때 발생하는 에러
=> 실행이 되다가 실행 중 문제 발생
에러 (error)
프로그램 코드에 의해서 수습될 수 없는 심각한 오류
예) Out of Memory Error
예외 (exception)
프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
에러는 어쩔 수 없지만, 예외는 처리하자!
- 논리적 에러 (logical error) : 작성 의도와 다르게 동작
=> 잘 동작은 하는데 개발자가 원하는대로 동작x
자바 컴파일러가 하는 일
1. 구문 체크
2. 번역
3. 최적화 예) int i = 3 +5;
4. 생략된 코드 추가
- 예외처리의 정의와 목적
예외처리(exception handling)의
정의
프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
목적
프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것
2. 예외 클래스의 계층 구조
Throwable : 클래스. 오류의 조상
Execption클래스들
사용자의 실수와 같은 외적인 요인에 의해 발생하는 에러 (예외처리 선택)
RuntimeException클래스들
프로그래머의 실수로 발생하는 예외 (예외처리 필수)
3. 예외 처리하기. try - catch문
try {
//예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (Exception2 e2) {
//Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (ExceptionN eN) {
//ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
}
if문과 달리, try블럭이나 catch블럭 내에 포함된 문장이 하나뿐이어도 괄호{}를 생략할 수 없다.
4. try - catch문에서의 흐름
① try블럭 내에서 예외가 발생한 경우,
1. 발생한 예외와 일치하는 catch블럭이 있는지 확인한다.
2. 일치하는 catch블럭을 찾게 되면, 그 catch블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행한다. 만일 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못한다.
② try블럭 내에서 예외가 발생하지 않은 경우,
1. catch블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속한다.
⍟실습
- 예외 발생 X
class Ex8_1 {
public static void main(String args[]) {
System.out.println(1);
try {
System.out.println(2);
System.out.println(3);
} catch (Exception e) {
System.out.println(4); //실행 안 됨
} //try-catch의 끝
System.out.println(5);
}
}
/*
결과
1
2
3
5
*/
- 예외 발생 O
class Ex8_2 {
public static void main(String args[]) {
System.out.println(1);
try {
System.out.println(0/0); //예외발생!
System.out.println(2); // 실행되지 않는다.
} catch (ArithmeticException ae) {
System.out.println(3);
} // try-catch의 끝
System.out.println(4);
} // main메서드의 끝
}
/*
결과
1
3
4
*/
5. 예외의 발생과 catch블럭
- 예외가 발생하면, 이를 처리할 catch블럭을 찾아 내려감
⍟실습
Ex8_4
class Ex8_4 {
public static void main(String args[]) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0/0); // 0으로 나눠서 고의로 ArithmeticException 발생
System.out.println(4); // 실행되지 않는다.
} catch (ArithmeticException ae) {
if (ae instanceof ArithmeticException)
System.out.println("true");
System.out.println("ArithmeticException");
} catch (Exception e){
// ArithmeticException을 제외한 모든 예외가 처리된다.
System.out.println("Exception");
} // try-catch의 끝
System.out.println(6);
} // main메서드의 끝
}
/*
결과
1
2
3
true
ArithmeticException
6
*/
6. printStackTrace()와 getMessage()
printStackTrace()
예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
getMessage()
발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
예외가 발생하면 해당 예외 객체가 발생한다.
이 객체에는 예외 정보와 printStackTrace(), getMessage()와 같은 메소드가 들어가 있다.
try {
...
System.out.println(0/0); // 예외발생!!
...
} catch (ArithmeticException ae){
ae.printStackTrace();
System.out.println(ae.getMessage());
} catch (Exception e){
...
}
ae는 참조변수. 따라서 예외객체의 주소가 들어가있다. 참조변수 ae의 유효범위는 해당 {} 안에서만 사용가능하다.
⍟실습
Ex8_5
class Ex8_5 {
public static void main(String args[]) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0/0); // 예외발생!!!
System.out.println(4); // 실행되지 않는다.
} catch (ArithmeticException ae) {
ae.printStackTrace();
System.out.println("예외메시지 : " + ae.getMessage());
} // try-catch의 끝
System.out.println(6);
} // main메서드의 끝
}
결과
1
2
3
java.lang.ArithmeticException : / by zero at Ex8_5.main(Ex8_5.java:8)
예외메시지 : / by zero
6
7. 멀티 catch 블럭
- 내용이 같은 catch블럭을 하나로 합친 것(JDK1.7부터)
주의 사항
1. 멀티 catch에 쓰이는 두 예외 클래스가 부모-자식이면 굳이 멀티catch 블럭을 쓸 필요가 없다.
instance of로 예외 클래스를 판단하기 때문이다. 즉, 꼭 일치하는 것을 판단하는 것이 아니다.
2. 멀티 catch에서 해당 에러에만 실행되는 메소드를 쓰지 말아라
try { ... } catch (ExceptionA | ExceptionB e){ e.methodA(); // 에러. ExceptionA에 선언된 methodA()는 호출불가 if(e instanceof ExceptionA){ ExceptionA e1 = (ExceptionA)e; // 형변환 e1.methodA(); // OK. ExceptionA에 선언된 메서드 호출가능 } else { // if(e instanceof ExceptionB) ...
📣 comment
구글링해보니 printStackTrace()의 경우는 보안성이나 오버헤드 등의 여러가지 문제로 사용하는 것을 지양한다고 한다. 마치 수업에서는 `System.out.println()` 을 사용하지만 현업에서 `System.out.println()`을 사용하지 않는 것처럼 말이다.
그래서 대신에 log framework를 사용해야한다고 한다.
출처
'🎥Back > 자바의 정석' 카테고리의 다른 글
[JAVA의 정석]사용자 정의 예외 만들기, 예외 되던지기 (0) | 2024.02.28 |
---|---|
[JAVA의 정석]예외발생시키기 (0) | 2024.02.28 |
[JAVA의 정석]열거형 (0) | 2024.01.19 |
[JAVA의 정석]제네릭 형변환 (0) | 2024.01.19 |
[JAVA의 정석]와일드카드, 제네릭 메서드 (0) | 2024.01.19 |