일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- codility
- 타입 객체
- Direct12
- 병행성
- 영속성
- I/O장치
- 자료구조
- DirectX 12
- 프로그래머스
- 락
- 알고리즘
- 파일시스템 구현
- 멀티쓰레드
- 그리디 알고리즘
- 컨디션 변수
- 그리디알고리즘
- 백준
- 스케줄링
- 병행성 관련 오류
- 쓰레드
- 운영체제
- DirectX12
- OS
- 다이나믹프로그래밍
- directx
- 다이나믹 프로그래밍
- 동적계획법
- 렌더링 파이프라인
- 디자인패턴
- 멀티프로세서
- Today
- Total
기록공간
예외 처리(Exception Handling) 본문
프로그램에서 발생하는 오류
프로그램에서 발생할 수 있는 오류는 크게 두 가지, 컴파일 오류와 런타임 오류로 나뉜다.
컴파일 오류
잘못된 문법을 사용하거나 변수 등을 정의하지 않은 상태에서 사용함으로 인해 컴파일 단계에서 발생하는 문법적인 오류
런타임 오류
프로그램을 실행하는 과정에서 발생되는 런타임 오류이다. 더욱 세분화 하면 세가지로 나눌 수 있다.
-
논리적 오류 : 개발자가 문제 분석을 잘못하거나 실수에 의해 엉뚱한 결과를 가져오게 되는 오류
-
시스템 오류 : 시스템 이상에서 발생되는 오류
-
예외사항(Exception) : 프로그램 실행 중 발생되는 비정상적인 상황
(ex. 어떤 수를 0으로 나눔, 배열범위를 벗어난 접근, 존재하지 않는 파일에 접근)
이런 다양한 오류 중에서 여기서 살펴볼 것은 예외사항에 대해 어떻게 처리 할것인가이다. 개발자는 이런 예외사항이 발생할 경우를 미리 예측해서 적절히 대응하기 위한 절차를 구현해야 한다. 이러한 구현을 위해 문법을 정리 해놓았는데 그것을 예외처리라고 한다.
Exception 클래스
예외는 프로그램 실행 중에 발생할 수 있는데, 명령어의 정상적인 흐름을 방해하는 이벤트로 자바에서 예외는 하나의 오브젝트(객체)이다. 프로그램 실행 중에 메소드 안에서 오류(Error)가 발생하게 될 경우, 메소드는 그 오류에 해당하는 예외 오브젝트를 만들고 그것을 자바 런타임 시스템(Runtime System)에 전달해준다. 즉, 자바 런타임 시스템에서 최종적으로 보고를 받는다.
자바에서 모든 예외 클래스는 Throwable 클래스나 Throwable 클래스의 하위 클래스를 상속받아 사용한다. Throwable 클래스는 예외를 설명하는 문장이나 예외가 발생할 때의 프로그램의 상태에 관한 정보를 포함하고 있다.
Throwable 클래스에서 파생된 클래스
-
Exception 클래스 : Exception 예외 클래스는 일반적으로 프로그래머에 의해 복원될 수 있는 예외 상황으로 메소드가 실행 중에 던지는 예외를 가리킨다.
-
Error 클래스 : 심각한 예외의 형태로 개발자가 복원할 수 없는 형태의 예외이다.
예외의 종류
-
checked exception : 메소드 내에서 예외가 발생한 경우 메소드를 정의할 때 throws 문에 메소드 내에서 발생할 수 있는 예외들을 명시해 주거나 또는 그 예외는 try ~ catch 에서 처리해 주어야만 하는 예외이다. 컴파일러가 컴파일을 수행하는 과정에서 checked exception이 throws 되는가의 여부 혹은 try ~ catch 되는지의 여부를 판단하여 프로그램에서 예외를 어떤 형식이든 처리하지 않으면 컴파일 자체가 불가능하다.
-
unchecked exception : 사전에 처리하지 않아도 컴파일러가 체크하지 않는 런타임 시에 발생할 수 있는 예외이다.
java.lang.throwable 클래스의 주요 메소드
-
toString() : Throwable 각각에 대한 설명을 문자열 형태로 반환한다.
-
printStackTrace(PrintStream s or PrintWriter w) : 표준 출력 스트림에 스택 호출 목록을 마지막 메소드부터 출력한다.
주요 런타임 예외 클래스
-
ArithmeticException : 수치 계산상의 오류 (0 나누기 등..)
-
ArrayStoreException : 배열에 잘못된 데이터 형을 저장하려 했을 경우 발생하는 오류
-
IndexOutOfBoundsException : 배열, 문자열, 벡터 등에서 인덱스 범위가 벗어난 경우 발생하는 오류
-
ClassCastException : 클래스 변환을 잘못한 경우 발생하는 오류
-
NullPointerException : 빈 객체를 참조하는 경우(초기화 되지 않은 변수 사용 등) 발생하는 오류
-
SecurityException : 자바의 내부 보안 사항을 위반하였을 경우 발생하는 오류
예외처리 방법
1. throws
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Test152
{
public static void main(String[] args) throws IOException
{
// BufferedReader 클래스 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 주요 변수 선언
int a, b, c;
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
c = a + b;
System.out.println("결과 : " + c);
}
BufferedReader 클래스의 메서드에서 입력 스트림을 읽어오는 readLine()을 사용하기 위해서는 사용하는 위치에서의 메서드(여기서는 main)가 IOException을 throws 해줘야 한다. 그러지 않는다면 checked exception으로 컴파일 자체가 불가능하다. 어떤 메서드 내에서 throws를 사용한다면 가장 바깥에 있는 메서드인 main까지 던져주거나 예외 처리를 해주는 곳까지 선언해주어야 컴파일이 가능해진다.
2. try ~ catch
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Test152
{
public static void main(String[] args)
{
// BufferedReader 클래스 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 주요 변수 선언
int a, b, c;
// 방법 <2>
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
//-- 메소드를 정의하는 과정에서 thorws 한 예외.
// 잡아내거나 던지지 않을 경우 컴파일 에러
System.out.println(e.toString());
}
}
}
try 블럭 내에서 처리된 코드 중 예외가 발생하는 경우 catch 블럭에서 잡아 처리한다. 이렇게 잡아내지 않는 경우에는 checked exception으로 컴파일 에러가 된다. 여기서는 IOException형을 잡아 처리하지만 그보다 더 상위 클래스인 Exception형을 잡아 처리할 수도 있다.
3. try ~ catch, catch, ...
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Test152
{
public static void main(String[] args)
{
// BufferedReader 클래스 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 주요 변수 선언
int a, b, c;
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 e1)
{
// IOException -> checked exception
//-- 메소드를 정의하는 과정에서 thorws 한 예외.
// 잡아내거나 던지지 않을 경우 컴파일 에러
System.out.println(e1.toString());
}
catch (NumberFormatException e2)
{
// NumberFormatException -> unchecked exception
//-- 런타임 시 발생할 수 있는 예외로
// 문법적으로 반드시 던질 필요도, 잡아낼 필요도 없다.
System.out.println(e2.toString());
System.out.println("숫자 형태의 데이터를 입력하세요~!!!");
}
}
}
catch를 여러번 사용하여 알맞은 예외를 잡아 그 예외에 맞는 처리를 할 수도 있다.
4. try~catch~finally
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Test152
{
public static void main(String[] args)
{
// BufferedReader 클래스 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 주요 변수 선언
int a, b, c;
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)
{
System.out.println(e.toString());
}
finally
{
System.out.println("고생많으셨습니다. 감사합니다.");
}
}
}
finally 블럭은 예외가 발생하든 발생하지 않든 언제나 실행되는 영역이다.
5. throw 키워드
class Demo
{
private int value;
public void setValue(int value) throws Exception
{
if(value<=0)
{
// 예외 발생
throw new Exception("value 는 0보다 작거나 같을 수 없습니다.");
}
this.value = value;
}
public int getValue()
{
return value;
}
}
public class Test156
{
public static void main(String[] args) //throws Exception
{
Demo ob = new Demo();
try
{
ob.setValue(-3);
int result = ob.getValue();
System.out.println(result);
}
catch (Exception e)
{
System.out.println("main() 에서 잡아낸 예외");
System.out.println(e.toString());
}
}
}
throw 키워드를 사용하면 사용자가 직접 예외를 던져줄 수 있다. 어떻게 보면 return과 같은 기능을 하지만 항상 예외를 던져줘야 한다는 점에서 차이가 있다. Exception 생성자 매개변수로 문자열을 받아 어떤 예외인지에 대한 설명을 직접 세팅 할 수 있다. throw를 하는 메서드를 호출한 위치에서는 이를 try~catch를 이용해 알맞게 처리하거나 또 throws를 하여 다음 바깥 메서드에서 처리할 수 있게 넘겨줘야 한다.
'Java' 카테고리의 다른 글
컬렉션 프레임워크 (Collection Framework) - 2 (list, Iterator...) (0) | 2020.09.18 |
---|---|
컬렉션 프레임워크 (Collection Framework) - 1 (stack, queue) (0) | 2020.09.16 |
Java의 주요 클래스(3) (0) | 2020.09.01 |
문자 집합 (Character Set) (0) | 2020.08.31 |
Java의 주요 클래스(2) (0) | 2020.08.27 |