컴파일시 일반 예외 vs 실행 예외 차이점
- 일반 예외가 발생할 가능성이 있는 코드는 빨간줄로 컴파일 에러를 발생시켜 예외처리 코드의 필요성을 알려줌
- 이 때 빨간 줄에 커서를 대면 Unhandled exception (처리되지 않은 예외)라고 뜬다.
- 실행 예외는 컴파일러가 그냥 넘겨버려서 컴파일에러는 뜨지않으므로 개발자가 경험을 토대로 예외 처리 코드를 작성해야한다.
예외 처리 코드 구조
try {
예외 발생 가능성이 있는 코드 작성
}
catch(예외클래스 e) {
- 예외가 발생하지 않은 경우 : catch 블록은 실행되지 않음
- 예외가 발생한 경우 : 즉시 실행을 멈추고 catch 블록의 예외 처리 코드 실행한 후 finally 블록 실행
}
finally {
- 생략 가능한 구역
- 예외 발생 여부와 관계없이 항상 실행됨
- try-catch 문에 return문이 있더라도 finally 블록은 항상 실행됨
}
일반 예외 처리 코드 예제 ( ClassNotFoundException )
- Class.forname() 메소드 : 매개값으로 들어온 클래스가 존재하는 클래스면 클래스의 객체를 리턴하고
존재하지않으면 ClassNotFoundException 예외를 발생시킨다.
public class ClassNotFoundExceptionExample {
public static void main(String[] args) {
try {
Class clazz = Class.forName("java.lang.String2");
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
}
클래스가 존재하지 않습니다.
이 경우는 일반 예외의 경우라서 컴파일 에러가 났기떄문에 처리하기가 쉽다.
실행 예외 처리 코드 예제 ( ClassNotFoundException )
public class TryCatchFinallyRunTimeExceptionExample {
public static void main(String[] args) {
String data1 = null;
String data2 = null;
try {
data1 = args[0];
data2 = args[1];
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
return;
}
try {
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.printf("%d + %d = %d\n", value1, value2, result);;
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요");
}
System.out.println("프로그램 종료");
}
}
<바로 Run을 실행한 경우>
실행 매개값의 수가 부족합니다.
<Run Configurations를 통해 실행 매개 값으로 문자열을 준 경우>
숫자로 변환할 수 없습니다.
다시 실행하세요
프로그램 종료
<Run Configurations를 통해 실행 매개 값으로 숫자를 준 경우>
200 + 300 = 500
다시 실행하세요
프로그램 종료
<프롬프트 창에서 실행시킨 경우>
다중 catch 블록
public class CatchByExceptionKindExample {
public static void main(String[] args) {
try {
String data1 = args[0];
String data2 = args[1];
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.printf("%d + %d = %d\n", value1, value2, result);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
System.out.println("프로그램을 종료합니다.");
}
}
- 예외 발생 가능 코드가 여러 개면 try-catch문을 여러 개 작성하는 것이 아니라
- try 안에 모든 실행 코드를 넣어주고 catch를 여러 개 만들면 된다.
- 어차피 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 가기 때문에 하나의 예외처리만 실행이 가능하다.
catch 순서
public class CatchOrderExample {
public static void main(String[] args) {
try {
String data1 = args[0];
String data2 = args[1];
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.printf("%d + %d = %d\n", value1, value2, result);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수 가 부족합니다.");
} catch(Exception e) {
System.out.println("실행에 문제가 있습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
System.out.println("프로그램 종료");
}
}
<매개값을 2개 받긴 했지만 숫자를 받지 않은 경우>
실행에 문제가 있습니다.
다시 실행하세요.
프로그램 종료
예외 떠넘기기
- 예외가 발생할 가능성이 있는 코드는 try - catch 블록으로 예외처리를 해주는 것이 원칙이지만
- throws [예외클래스] 형태로 예외를 떠넘길 수도 있다.
- 여기서 throws 가 사용된 메소드는 반드시 호출할 때에는 try-catch 문을 쓰거나 또다시 throws를 해야한다.
- 예를 들어 method2() 선언시 throws를 해주었다면 method2()를 호출하는 곳(method1)에서는 반드시 try-catch를 사용하여 try 블록안에서 메소드를 호출해야한다.
- 하지만 method1()에서도 try-catch문을 사용 안하고싶다면 또 method1 선언시 throws를 해주면 된다.
- 그럼 이제 method1()을 호출하는 곳인 method0()에서는 반드시 try-catch문을 사용해주어야한다.
예외 떠넘기기 예제 - ClassNotFoundException
public class ThrowsExample {
public static void main(String[] args) {
try {
findClass();
} catch (ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
public static void findClass() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
}
클래스가 존재하지 않습니다.
main() 메소드에서 throws Exception을 사용하면 안되는 이유
- 우선 main() 메소드에서도 throws로 예외를 떠넘길 수 있지만 그렇게되면 결국 JVM이 최종적으로 예외를 처리하게 됨
- 그런데 이는 사용자가 예외 내용을 알 수 없는 상태로 프로그램이 종료되므로 바람직하지 않다.
- 따라서 main() 메소드에서 try-catch 블록을 사용하여 최종적으로 예외 처리를 해주는 것이 바람직하다.
'👨💻 2. 웹개발_Back end > 2-1 Java' 카테고리의 다른 글
[JAVA] 11-2 java.util 패키지 (0) | 2021.08.13 |
---|---|
[JAVA] 11-1 java.lang 패키지 (0) | 2021.08.13 |
[JAVA] 10-1 예외 클래스 (0) | 2021.08.11 |
[JAVA] 09-2 익명 객체 (0) | 2021.08.11 |
[JAVA] 09-1 중첩 클래스와 중첩 인터페이스 소개 (0) | 2021.08.11 |
댓글