Java (Exception)

yihyun·2024년 8월 1일

Java

목록 보기
9/12
post-thumbnail

예외(Exception)

프로그래밍을 하면서 가장 두려운 것, 그리고 당황스러운 것은 예외이다. (일단 나는 그렇다.)

하지만 프로그래밍을 잘 하려면 이러한 예외를 두려워하면 안된다!
우리가 흔히 말하는 오류에는 예외와 에러가 있는데, 그 둘의 차이는 다음과 같다.

❕ 예외와 에러의 차이

  • 에러(Error) : 문법이나 메모리 사용 문제로 실행에 문제가 생겨 발생하는 오류 *개발 중 개발자의 실수로 발생하는 것
  • 예외(Exception) : 사용자의 오조작이나 외부 문제로 발생하는 오류

❔ 다음 예시를 보고 예외인지 에러인지 맞춰보자!

  1. 파일을 읽어오는 도중에 network 사정으로 깨졌다 → Exception
  2. 내가 만든 method에서 숫자형 변수에 문자열 데이터를 넣었다. → Error
  3. 취미 5개를 넣으라고 했는데 사용자가 8개를 넣었다. → Exception
  4. 선언하지 않은 method를 호출했다. → Error

예외는 일반 예외(Exception)와 실행 예외(Runtime Exception)로 분리된다.

  • Exception : Compile time 에 실행되는 exception, coding 중에 알 수 있다. (이클립스가 빨간 줄로 알려준다.) → 일반 예외는 JVM 에서 필요하다고 판단하면 자동으로 예외처리를 해준다.

  • Runtime Exception : Run time에 실행되는 exception, 실행 해 봐야 알 수 있다.

대표적인 Runtime Exception 종류에는 4가지가 있다.

  • NullPointException : 객체가 없는 상태에서 객체를 사용할 경우 (Null은 진공의 상태인데 그걸 내가 열어버렸을 때 → 진공상태는 안에 무언갈 채워넣고 해야한다.)
String data = null; // 숫자는 null이 존재하지 않는다.
data.contains("a");
  • ArrayIndexOutofBoundException : 배열 인덱스 범위를 초과하여 사용할 경우 *컬렉션 프레임워크를 사용하면 해결 가능!(배열이 무한으로 늘어날 수 있기 때문에)
String[] arr = new String[2]; // 2개 짜리 방 생성
		
arr[0] = "data1";
arr[1] = "data2";
arr[2] = "data3"; // 2번 인덱스는 존재하지 않는다.
  • NumberFormatException : 숫자 변환 시 문자가 포함되어 있는 경우 ("1","2" 가 아닌 "a" 이런 진짜 문자열이 들어오는 경우)
String data;
int vla;

data = "1234";
val = Integer.parseInt(data); // 1234로 변환

data = "1234a";
vla = Integer.parseInt(data); // 예외 발생
  • ClassCastException : 매개 값으로 받은 타입의 종류를 알 수 없는 경우
Object value = 1234;
String str = (String) value; // 숫자 형태가 문자로 집을 잘못 찾아감

예외 확인방법
1. 무슨 Exception인지 확인한다.
2. 오른쪽으로 가서 이유를 확인한다.
3. at에는 정확한 위치가 나온다. (아래서부터 위로 읽는다.)

Exception은 불가피한 외부 문제로 발생하기 때문에 프로그램이 정지하지 않도록 해야한다.
그래서 예외 처리를 통해 exception 발생 시에도 프로그램이 정상 작동 하도록 하기 위해 try-catchthrows 라는 두 가지 방법을 사용한다.

try-catch : 문제 발생 시 스스로 해결한다.
throws : 해당 업무를 시킨 method에 전가한다.

try-catch

try-catchtry 영역 안에서 exception발생 시 catch를 실행하는 구문이다.
Finallyexception 발생시에도 꼭 실행할 code를 작성해준다.

try{ //예외 발생 가능 코드
	김대리가 박 부장에게 보고서를 올린다;
    보고서를 검토한다;
    문제 없으면 잘했다고 한다;
} catch(Exception e) { // 예외 발생 시 실행 코드
	오류 부분 e를 지적하고 다시 하라고 한다.
} finally{ // 무조건 실행
    자리로 들어 가라고 한다;
}    

하지만 Exception이 꼭 하나만 발생하라는 법은 없다.
이런 경우에는 몇 가지 해결 방법이 있는데

1. 각 Exception에 맞는 catch를 만들어준다.
이 방법은 예외 마다 처리 방법을 세세하게 지정해 줄 수 있다는 장점이 있다.

2. multi catch (묶어서 해결) *java 1.7부터 지원
이 방법은 비슷한 예외를 묶어서 처리하기 때문에 조금 더 간편하게 사용할 수 있다.

catch(ArrayIndexOutOfBoundsException | NumberFormatException e) {
	e.printStackTrace();
}

3. Exception을 모두 한번에 처리
다형성을 이용해 모든 Exception을 한번에 처리해준다.

catch(Exception e){
	e.printStackTrace();
}

e.toString() : 예외의 정보를 간단하게 보는 방법
e.printStackTrace() : 예외의 정보를 상세하게 보는 방법
→ 개발 할 때만 사용하고 개발이 끝나고 나면 주석처리 또는 빼줘야 한다. (외부에 노출되면 위험하기 때문)

throws

throws 는 책임을 전가하는 것이라고 했는데, 책임 전가란 본인을 호출한 메소드에게 처리를 시키는 것이다.
main()에서도 throws를 할 경우 JVM에서 처리하게 된다. (예외 내용 콘솔 출력)

이는 같은 예외를 여러 곳에서 처리하는 등의 코드의 중복을 줄일 수 있다.

public class Sub {
	
//	main에게 문제를 던진다. (나한테 일을 시킨 사람에게 던지는 것이다.)
//	method1이 해결할 생각이 없으니 또 다시 던진다.
	void method1() throws Exception{
		method2(); // method2 에게 일을 시킨다.
	}
	
//	method1 에게 문제를 던진다. 
	void method2 () throws NumberFormatException {
//		혼자 일을 처리한다.
		Integer.parseInt("a1234"); // 처리하다가 문제 발생
	}

}

public class Main {

//	JVM(자바의 신) 에게 던진다. -> 책임을 지는 것이 아닌 printStackTrace를 찍어주고 끝난다. 
	public static void main(String[] args) throws Exception {

		Sub sub = new Sub();
		
//		method1 에게 일을 시킨다. 
		sub.method1();
		
	}

}

사용자 예외(Custom Exception)

우리는 기존예외 이외에도 새로운 예외를 만들 수 있다.
이는 주로 테스트를 위해 강제로 특정 예외를 발생시킬 수 있는데 반드시
[Exception | RuntimeException] 클래스를 상속 받아야 한다.


정리
1. 예외란 사용자의 오 조작이나 외부 문제로 발생하는 오류를 말한다.
2. 예외 발생 시 프로그램이 멈추지 않고 진행할 수 있도록 예외처리를 해준다.
3. try-catch 는 예외가 발생하는 곳에서 처리하는 방법이다.
4. throws는 작업을 지시한 메서드에게 처리를 넘기는 것이다.
5. Runtime Exception 은 실행해봐야 알 수 있다.
6. Exception은 coding 중에 알 수 있다.
7. 모든 exception의 부모는 Exception class 이다.

profile
개발자가 되어보자

0개의 댓글