예외(Exception) 처리
프로그램에서 발생하는 오류는 컴파일 오류와 런타임 오류 두 가지로 나눌 수 있다.
1. 컴파일 오류
- 잘못된 문법을 사용하거나 변수 등을 정의하지 않은 상태에서 사용함으로써
컴파일 단계에서 발생하는 문법적인 오류
2. 런타임 오류
- 프로그램을 실행하는 과정에서 발생하는 런타임 오류
런타임 오류는 두 가지로 나눌 수 있는데 시스템 이상에서 발생하는 시스템 오류(Error),
프로그램 실행 중 발생되는 비정상적인 상황을 의미하는 예외사항(Exception).
Exception은 개발자가 고칠 수 있지만 Error는 고칠 수 없음 !
Exception 클래스
- 자바에서 예외는 하나의 객체
- 프로그램 실행 중 오류가 발생할 경우, 메소드는 그 오류에 해당하는 예외 객체를 만들고
그것을 자바 런타임 시스템에 전달 -> 따라서 예외처리를 해주지 않아도 에러를 알려줬던 것 !
- 자바에서 모든 예외 클래스는 Throwable 클래스나 그 하위 클래스를 상속받아 사용
Throwable 클래스의 하위 클래스
▶ Exception 클래스 (메소드가 실행 중에 던지는 예외)
▶ Error 클래스 (개발자가 복원할 수 없는 형태의 예외)
예외의 종류
- checked exception
▶ 메소드 내에서 예외가 발생한 경우
▶ 메소드를 정의할 때 throws 문에 예외를 명시해주거나 try~catch 해서 처리해 주어야만 하는 예외
▶ 프로그램에서 예외를 처리해주지 않으면 컴파일 자체가 불가능
ex) throws IOException (우리가 항상 해주던 이 예외가 checked exception !! 신기하다)
throws UnsupportedEncodingException
- unchecked exception
▶ 런타임 시에 발생할 수 있는 예외
▶ 사전에 처리할 필요 X, 컴파일러가 체크 X
ex) IndexOutOfBoundsEncodingException
▶ 주요 런타임 예외 클래스
- ArrayStoreException, IndexOutOfBoundsException, NullPointerException...
java.lang.Throwable 클래스의 주요 메소드
- toString() (Object 클래스의 toString() 오버라이딩)
: 에러의 Exception 내용과 원인을 반환 (위치는 X)
- printStackTrace()
: 에러의 발생 근원지를 찾아서 단계별로 에러를 출력
- getMessage()
: 에러의 원인을 간단하게 반환
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
c = a + b;
System.out.println("결과 : " + c);
}
catch (IOException e)
{
// IOException → checked Exception
//-- 메소드를 정의하는 과정에서 throws 한 예외
// 잡아내거나 던지지 않을 경우 컴파일 에러 발생 -> 따라서 예외를 잡아내고 있다
System.out.println(e.toString());
}
IOException 예외는 checked error 로 던지거나 잡아내지 않으면 컴파일 자체가 불가능하다.
따라서 위 코드에서는 예외를 잡아내고 있다.
그러나 NumberFormatException 과 같은 unchecked error 는 반드시 던질 필요도, 잡아낼 필요도 없다.
이와 같이 특정 예외 객체를 잡아낼 수도 있고
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
c = a + b;
System.out.println("결과 : " + c);
}
catch (Exception e)
{
System.out.println(e.toString());
System.out.println(e.getMessage());
System.out.println("printStackTrace...");
e.printStackTrace();
위의 코드와 같이 예외를 모두 Exception 객체로 처리하여 해당 예외의 내용을 출력할 수도 있다.
finally
예외가 발생해도 발생하지 않아도 언제나 실행되는 영역을 설정할 수 있는데, finally 를 사용하면 된다.
try
{}
catch
{}
finally
{}
이런 식으로 finally 블럭을 추가하여 그 내용을 넣어주면 된다.
메소드에서 조건을 검사하여 조건에 어긋날 때 return을 사용할 수 있지만,
에러를 발생시켜 프로그램을 종료하는 것이 좋을 때도 있다 ! (Test152, Test153 비교)
public void setValue(int value) throws Exception
{
if(value <= 0)
{
//return; -- 종료 → 메소드 종료
throw new Exception("value 는 0보다 작거나 같을 수 없습니다."); // 폭탄을 품고 있는 상태 (던져줘야한다!)
}
this.value = value;
}
위의 코드에서는 해당 메소드만 종료시키는 return 대신, 새로운 예외를 발생시키고 있다.
이렇게 예외를 직접 발생시키면 프로그램 전체를 종료시킬 수 있다 !!
예외 다시 던지기
잡아낸 예외를 다시 던질 수 있다. 이렇게 하는 이유는 상위 계층에 예외를 알리기 위해서 ! 라고 배웠다..!
public int getData(int data) throws Exception
{
if(data<0)
{
throw new Exception("data가 0보다 작습니다.");
}
return data + 10;
}
public int getValue(int value) throws Exception
{
int a = 0;
try
{
a = getData(-2);
}
catch (Exception e)
{
System.out.println("ⓐ printStackTrace.....");
e.printStackTrace();
}
return a;
}
또한 이런식으로 메소드 내부에서 예외를 던졌다면 그 메소드를 사용한 곳에 예외 (폭탄이라 생각하자!!)가
떨어지므로 이 예외를 또 던져줘야 한다!!
위의 코드를 보면 getData()를 사용한 곳에서 Exception을 다시 throws 하는 것을 알 수 있다.
예외 처리 너무 어렵다...............
무슨 원리인지는 대충 이해가 가는데........
Throwable 클래스의 메소드들이 아직은 너무 낯설고 어렵다!
많이 접해봐야지
'공부 > Java' 카테고리의 다른 글
웹 어플리케이션과 싱글톤 (0) | 2024.05.07 |
---|---|
스프링 핵심 원리 이해 - 객체 지향 원리 적용 (0) | 2024.05.07 |