throw와 throws 키워드는 비슷하지만 다른 용도로 사용됩니다.
throw
는 Exception을 발생시킬 때 사용하는 키워드입니다.
만약 어떤 연산을 하다가 예상치 못한 일이 발생했을 때 Exception을 발생시켜 예외가 처리될 수 있도록 합니다.
Application이 예외를 적절히 처리하지 못하면 프로그램이 죽거나 오동작하게 됩니다.
반면에 throws
는 메소드를 정의할 때 사용하며, 이 메소드에서 발생할 수 있는 Exception을 명시적으로 정의할 때 사용합니다.
따라서 throws를 보면 잠재적으로 어떤 Exception을 발생될 수 있는지 쉽게 알 수 있습니다.
Throw
Integer.parseInt()
는 인자로 전달된 문자를 Integer로 변환합니다.
만약 아래와 같이 숫자가 아닌 문자열을 인자로 전달하면 Exception이 발생하면서 프로그램이 죽게 됩니다.
String numStr = "11a";
int num = Integer.parseInt(numStr);
Output:
Exception in thread "main" java.lang.NumberFormatException: For input string: "11a"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
Integer.parseInt()
의 코드를 보면, 예상 밖의 인자가 전달되었을 때 Exception을 throw하도록 구현되어있습니다.
public static int parseInt(String s, int radix) throws NumberFormatException
{
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
....
}
catch
만약 Exception이 발생했을 때 프로그램이 죽지 않게 하려면 다음과 같이 catch 키워드로 예외를 처리해야 합니다.
Integer.parseInt()
에서 NumberFormatException이 발생하면 그 아래에 있는 코드들이 수행되지 않고 catch에 있는 코드가 실행됩니다.
String numStr = "11a";
int sum = 0;
int num = 0;
try {
int num = Integer.parseInt(numStr);
sum = sum + num;
} catch (NumberFormatException e) {
// catch exception
num = 0;
sum = 0;
}
위의 예제는 NumberFormatException가 발생했을 때만 catch
코드가 수행되며 예외를 처리합니다. 만약 RuntimeException이 발생하면 예외를 처리하지 못하여 프로그램이 죽습니다.
만약 다음과 같이 catch (Exception e)
으로 Exception에 대해서 예외를 처리하면 거의 모든 예외가 처리될 수 있습니다.
try {
int num = Integer.parseInt(numStr);
} catch (Exception e) {
// catch exception
}
다음은 NumberFormatException이 발생했을 때, 이 예외를 처리하고 IllegalArgumentException
라는 다른 예외를 발생시키는 예제입니다.
String numStr = "11a";
try {
int num = Integer.parseInt(numStr);
} catch (NumberFormatException e) {
// catch exception
throw new IllegalArgumentException("This string is not a number format");
}
예외의 종류를 변경하거나 메시지를 변경할 때 이렇게 구현할 수 있습니다.
위 코드를 실행하면 다음과 같이 재정의한 Exception과 메시지가 출력됩니다.
Exception in thread "main" java.lang.IllegalArgumentException: This string is not a number format
at example.throwandthrows.Example.main(Example.java:36)
Multi catch
여러 Exception이 발생할 수 있는 경우, 다음과 같이 catch를 사용하여 여러개의 Exception을 잡을 수 있습니다.
try {
int num = Integer.parseInt(numStr);
} catch (NumberFormatException e) {
// catch exception
} catch (IllegalArgumentException e) {
// catch exception
}
catch (Exception e)
으로 거의 모든 예외를 잡을 수 있지만, 각각의 예외마다 다르게 처리해야하는 경우 위처럼 구현할 수 있습니다.
Exception, Throwable
Exception의 상속구조를 알아보려고 합니다.
다음 코드는 Exception 클래스입니다. Exception은 Throwable을 상속합니다.
public class Exception extends Throwable {
...
}
그 외의 다른 많은 Exception들은 다음과 같이 Exception 클래스를 상속합니다.
public class RuntimeException extends Exception {
...
}
대부분 Exception 클래스를 상속하기 때문에 catch (Exception e)
와 같은 코드는 대부분의 예외를 잡아낼 수 있게 됩니다.
Custom Exception
Java는 IllegalArgumentException, NumberFormatException 등의 Exception을 기본적으로 제공하지만 다음과 같이 직접 Exception을 정의할 수도 있습니다.
public class InvalidNumberException extends Exception {
public InvalidNumberException(String message) {
super(message);
}
}
위에서 정의한 Exception은 다음과 같이 사용될 수 있습니다.
if (desX < 0 || desY < 0) {
throw new InvalidNumberException("It's not allowed a number under 0 : (x: "
+ desX + ", y: " + desY);
}
Throws
Throws는 메소드에서 잠재적으로 어떤 Exception이 발생할 수 있는지 명시하는 키워드입니다.
다음은 예제로 만든 InputEvent 클래스입니다. moveTo()
메소드의 정의에 throws NumberFormatException
라고 정의함으로써, 이 메소드를 사용할 때 NumberFormatException가 발생할 수 있음을 알려줍니다.
public class InputEvent {
private int x;
private int y;
public InputEvent(int x, int y) {
this.x = x;
this.y = y;
}
public void moveTo(int desX, int desY) throws NumberFormatException {
if (desX < 0 || desY < 0) {
throw new NumberFormatException("It's not allowed a number under 0 : (x: "
+ desX + ", y: " + desY + ")");
}
this.x = desX;
this.y = desY;
}
}
그래서 사용할 때 다음과 같이 catch를 써주면 좋습니다.
InputEvent event = new InputEvent(10, 20);
try {
event.moveTo(-1, -2);
} catch (NumberFormatException e) {
// ignore
}
아래 코드는 Object 클래스의 wait()
메소드입니다. 이런식으로 JavaDoc에 어떤 상황에서 Exception이 발생하는지 @throws
으로 자세히 명시할 수 있습니다.
/**
* Causes the current thread to wait until another thread invokes the
.....
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
*/
public final void wait() throws InterruptedException {
wait(0);
}
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기