JAVA
1. 예외 처리
에러(error)와 예외(exception)
자바 프로그램을 실행하다 보면 갑자기 프로그램이 종료되거나, 어떤 원인에 의해 잘못 동작하여 오류 메세지가 나타나는 등 예기치 못한 오류가 발생합니다.
전자는 우리가 해결할 수 없는 시스템에 에러가 발생해 프로그램이 종료된 경우이며 후자는 프로그램 사용 중 발생한 오류를 개발자가 처리해 메세지가 출력된 경우입니다.
자바는 에러 또는 예외가 발생하는 경우, 해당 사항을 클래스로 관리합니다. 컴파일 또는 실행 중에 문제가 발생하면 해당
문제에 따른 클래스 객체를 생성합니다. 이 클래스를 이용해서 프로그램 동작 중에 발생하는 예외들을 처리할 수 있습니다.
에러(error)
에러는 시스템에 비정상적인 상황이 생겻을 때 발생합니다. 외부 요인일 수도 있고, 프로그램 구둥 중에 발생하는 치명적
오류일 수도 있습니다. 이러한 에러들은 개발자가 예측하거나 처리할 수 없는 영역입니다.
[에러 종류]
에러의 종류 | 상황 |
OutOfMemoryError | 프로그램 실행 중 메모리 부목 |
IOError | 입출력 에러 |
StackOverFlowError | 가용 메모리 부족 현상, 재귀 호출 문제 시 발생 |
예외(exception)
예외란 대체로 프로그램 구동 중에 나타나는 오류들을 말합니다. 문법적으로는 문제없어 보이지만 실제 운영 중에 생기는
문제들입니다. 예외는 체크 예외(checked exception)와 비체크 예외(unchecked exception) 두 가지가 있습니다.
체크 예외는 자바 소스를 컴파일하는 과정에서 검사하여, 보통 문법적으로 강제하여 예외를 처리하는 경우이고,
비체크 예외는 컴파일 과정에서 검사하지 않으므로 사용자의 경험이나 테스트로 찾아야 하는 경우가 있습니다.
[체크 예외와 비체크 예외 구분 기준]
구분 | 체크 예외 | 비체크 예외 |
처리 여부 | 문법적으로 예외 처리를 강제함 반드시 처리 해야 함 |
문법적으로 강제하지 않음 개발자의 판단에 의해 처리 |
확인 시점 | 컴파일 단계 | 실행 단계 |
예외 클래스 | Runtime Exception을 제외한 모든 예외 IOException SQLException 등 |
Runtime Exception의 자식 클래스 모두 포함 NullPointerException IndexOutOfBoundException ClassNotFoundException 등 |
2. 예외 클래스
자바는 객체 지향 언어입니다. 따라서 프로그램에서 발생하는 예외들은 클래스의 형태로 제공됩니다.
최상위의 Throwable을 상속받은 에러와 예외가 있습니다. 에러는 시스템상의 심각한 수준의 오류이기 때문에 수습될 수 없는 반면에 예외는 개발자가 로직을 추가하여 철리할 수 있습니다. 예외는 또다시 체크예외와 비체크 예외로 구분됩니다.
프로그램을 구동할 때 예외가 발생하면 시스템은 무슨 이유로 예외가 발생했는지 예외 클래스를 에러 메세지로 출력해 줍니다. 해당 메세지를 살펴보면 어떤 예외를 처리해야하는지 알 수 있습니다. 따라서 모든 예외 클래스를 암기하지 않아도 됩니다.
NullPointerException
NullPointerException은 자바 프로그램에서 가장 빈번하게 발생하는 실행 예외입니다. 객체가 제대로 생성되지 않은 상태에서 사용할 경우 발생합니다. 객체를 선언하면 인스턴스는 객체의 주소를 가지게 되고, 그것을 통해 객체에 접근해 값을 가져옵니다. 그런데 객체는 정의되었는데 실제 메모리에 생성되지 않았을 경우, 예외가 발생합니다. (주어가 없을 때)
NumberFormatException
NumberFormatException은 잘못된 문자열을 숫자로 형 변환할 때 발생합니다. 숫자 형태("111")의 문자열을 정수 타입으로
변환할 수 있으나 문자가 포함되거나 실수 형태("11.11")의 문자열은 변환할 수 없습니다.
정수는 실수를 포함하지 않기 때문에 소수점을 문자로 인식합니다.
ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException은 배열에서 인덱스(index) 범위를 초과해 사용할 때 발생합니다.
3. 예외 처리 문법
예외 처리 과정
1. 코드 진행중 예외가 발생하면 JVM에게 알림
2. JVM은 발생한 예외를 분석하여 알맞은 예외 클래스를 생성함
3. 생성된 예외 객체를 발생한 지점으로 보냄
4. 예외가 발생한 지점에서 처리하지 않으면 프로그램은 비정상 종료됨
위와 같이 예외가 발생하면 시스템(JVM)에서 분석하여 예외 클래스중 알맞은 것을 발생시키고 발생 지점으로 던지게 됩니다. 이를 처리하지 않으면 프로그램은 비정상으로 종료됩니다. 그래서 넘어온 예외를 처리해 프로그램을 비정상으로 종료되지 않고 구동할 수 있도록 해야 합니다.
try - catch 구문
예외를 처리하는 가장 기본 문접은 try - catch문 입니다. 발생한 예외를 처리하기 위해서 try - catch 구문을 사용하게 됩니다. 예외가 발생할 가능성이 있는 코드 try{...}안에 작성하고 catch메서드는 시스템으로부터 넘어오는 예외 클래스를 받아서 처리합니다.
try블록에는 예외 발생 가능성이 있는 코드가 위치합니다. catch 메서드에는 처리할 예외의 클래스를 파라미터로 둡니다.
그러면 해당 예외가 발생했을 때, catch를 통해서 제어 및 처리를 할 수 있습니다.
예외를 처리할 때 Exception 클래스를 이용하면 모든 예외를 처리할 수 있습니다. Exception은 모든 예외 클래스의 최상위 객체이기 때문에 catch에서 사용하면 모든 예외 처리가 가능합니다. (부모 클래스는 자식을 수용할 수 있기 때문)
다중 catch 사용하기
프로그램을 구동할 때 하나의 예외만 발생한다면 처리하기는 어렵지 않습니다. 하지만 try 구문 안에서 예외는 다양하게
발생할 수 있습니다. 만약 기존과 같은 방법으로 처리한다면 하나의 예외를 제외하고는 제대로 처리할 수 없기 때문에
다중 catch 문을 예외별로 예외 처리 코드를 다르게 하여 다양한 예외 처리를 할 수 있습니다.
catch 문은 하나의 예외를 처리하도록 되어있습니다. 코드에서 하나의 예외가 발생하면 그 위치에서 실행을 멈추고 해당 예외를 처리하는 catch블록으로 이동하게 됩니다.
예외를 다중 처리하여 프로그램을 구성하면 코드에 발생하는 다양한 예외를 처리할 수 있습니다. 따라서 보다 안정적인
프로그래밍이 가능해집니다.
다중 catch 문을 사용할 때는 순서에 유의해야합니다. Exception을 catch 문 맨 앞에 사용하면 문법 에러가 발생합니다.
그 이유는 Exception은 예외 객체의 최상위 클래스이기 때문에 맨 앞에서 예외를 처리하게 되면 뒤에 있는 다른 예외들은
불필요해지기 때문입니다. 따라서 Exception처럼 상위 예외 클래스를 처리하는 코드는 catch 문 맨 마지막에 작성합니다.
finally
finally 블록은 예외 발생 유무와 상관없이 실행되는 구문이며 생략할 수 있습니다. 예외 처리를 할 때, 예외와 상관없이
반드시 처리해야 하는 구문들을 작성할 때 사용되며, 보통 외부 연동이나 예외가 발생해도 정상 종료되어야 할 구문들에서사용합니다.
public class ExceptionExample{
public static void main(String[] args){
try{
예외 발생이 예상되거나 의심되는 실행 코드
}
catch(예상 예외 클래스 혹은 Exception e){
예외 처리
}
finally{
예외와 상관없이 실행되는 코드
}
}
}
4. 예외 던지기
호출한 메서드에서 예외가 발생할 경우, 메서드 내부에서 try - catch 문으로 예외를 처리할 수 있습니다. 그런데 메서드
내부에서 예외를 처리하지 않고 미룬 후, 해당 메서드를 호출한 쪽에서 예외를 처리하도록 하는 방법도 있습니다.
그것을 '예외 던지기' 또는 '책임 전가' 라고 합니다. 때로는 직접 처리하는 것보다 해당 메서드를 사용한 곳에서 처리하도록
하는 것이 효율적일 때가 있습니다.
throws 키워드
예외 던지기는 throws 키워드를 사용합니다. 메서드 뒤에 throws 키워드를 사용하여 던지기 할 예외 객체를 붙여줍니다.
예외 객체는 여러개를 던질 수 있으며, 여러 개를 던질 시에는 콤마(,)로 구분해서 나열해 줍니다.
예외 던지기를 하는 이유는 메서드에서 예외를 각각 처리하면 메서드 자체의 코드가 길어지거나, 유지 보수 측면에서
효율이 떨어질 수 있습니다 이때, 메서드를 호출하는 쪽에서 예외를 처리해 주면 좀 더 수월하게 처리할 수 있기 때문에입니다.
예외 던기기는 예외 클래스를 여러개 던질 수 있습니다.
void 메서드명 throws NullPointerException, ClassNotFoundException, ..{}
위와 같은 메서드를 호출하는 쪽에서는 다중 catch문을 사용해 처리해야 합니다.
임의의 예외 처리 방법
프로그램을 작성하다 보면 코드의 오류로 발생하는 예외도 있지만, 프로그램의 규칙에 위배되어 예외를 발생해야 하는
경우도 있습니다. 만약, 프로그램의 규칙에 위배되어 예외를 발생해야 할 경우, 임의로 예외를 발생시킬 수 있습니다.
임의의 예외 처리는 다음과 같은 특징을 가지고 있습니다.
정의 | 예외 발생 상황이 아디더라도, 필요에 의해 강제로 예외를 발생시키는 기능 |
발생 방법 | throw new 예외 객체(메세지); |
발생 위치 | try - catch 내부 또는 메서드에 예외 던지기가 있는 경우 |
용도 | 개발자 예외를 의도하는 위치 |
표와 같이 임의로 발생시키는 예외 처리는 개발자의 의도로 인해 발생합니다. try - catch 문의 내부 또는 예외 던지기가
구현된 메서드 안에서 발생시킬 수 있습니다.
5. 사용자 정의 예외 처리
자바가 제공하는 예외 객체 외에도 개발자가 목적에 의해서 예외 객체를 만들 수 있으며, 이를 사용할 수 있습니다.
자바가 제공하는 예외 객체는 다양하지만 모든 예외를 처리하기는 어렵고 목적에 따라 공통기능을 지니는
예외 처리도 필요하기 때문에 개발자가 직접 예외를 생성하여 처리합니다.
[체크 예외]
public class CustomException extends Exception{
}
[비체크 예외]
public class CustomException extends RuntimeException{
}
위와 같이 사용자가 만든 클래스 Exception 또는 RuntiomeException을 상속하면 해당 클래스를 예외 처리 객체로 사용할 수 있습니다. 체크 예외를 만들고 싶다면, 최상위 객체인 Exception을, 비체크 예외를 만들고 싶을 때는
RuntimeException을 상속합니다. 사용자 정의 예외 객체는 개발자가 직접 만든다는 점을 제외하면 사용 방법은 기존 예외 객체들과 동일합니다.
응용문제
1. 다음 코드는 컴파일 오류가 발생합니다. 오류를 확인하고 예외 처리 문법을 사용하여 해결해 보세요.
public class ValueExceptionExample{
public static void main(String[] args){
int data = 10;
double result = 0;
result = (double)data / 0;
System.out.println("결과는 : "+result);
}
}
정답 :
public class ValueExceptionExample{
public static void main(String[] args){
int data = 10;
double result = 0;
try{
result = (double)data / 0;
}
catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없습니다");
}
System.out.println("결과는 : "+result);
}
}
2. 다음 코드에서 사용자가 음수를 입력할 경우 임의로 예외를 발생시켜 음수의 값을 합산에 포함되지 않도록 처리해 보세요.
import java.util.Scanner;
public class MinusValueException{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int count = 5;
int data = 0;
int sum = 0;
while(count < 5){
System.out.println("숫자를 입력하세요 >> ");
data = sc.nextInt();
sum += data;
}
System.out.println("숫자 합 : "+sum);
}
}
정답 :
import java.util.Scanner;
public class MinusValueException{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int count = 5;
int data = 0;
int sum = 0;
while(count < 5){
try{
System.out.println("숫자를 입력하세요 >> ");
data = sc.nextInt();
if(data == -1){
break;
}
if(data < 0}{
throws new Exception("음수는 입력할 수 없어요.");
}
sum += data;
}
catch(Exception e){
sc.nextLine();
System.out.println("에러 메세지 : "+e.getMessage());
}
}
System.out.println("숫자 합 : "+sum);
}
}
'javaboiii의 JAVA > JAVA 요약정리(멘토씨리즈)' 카테고리의 다른 글
JAVA - 16) 컬렉션 프레임워크(Collection Framework) (0) | 2024.07.27 |
---|---|
JAVA -15) 기본 API 클래스 (0) | 2024.07.26 |
JAVA -13) 내부 클래스 (2) | 2024.07.24 |
JAVA -12) 추상 클래스와 인터페이스 (4) | 2024.07.23 |
JAVA -11) 다형성과 타입 변환 (0) | 2024.07.22 |