우와한 개발자

[Java] 예외(Exception) - try catch문, throws, throw , 예외 종류

by 우와한개발자

1. 예외처리(Exception Handling)란?

예외처리(Exception Handling)는 프로그램 실행 중 발생할 수 있는 오류 상황에 대비하는 방법

1) 오류 Error

  • 심각한 오류
  • 발생시 프로그램 중지/복구불가
  • 메모리부족 OutOfMemoryError 등

 

2) 예외 Exception

  • 심각하지 않은 오류
  • 발생시 예외를 처리하여 프로그램 계속 실행가능
  • FileNotFoundException, ArrayIndexOutOfBoundsException 등

 

3) 예외 처리 방법 

  • try ~ catch문(직접해결)
  • throws 선언문(메서드 호출한 곳으로 예외발생알림)

 

2. try ~ catch ~ finally

  • 예외의 원인이 현재 실행되는 블록에 있을 경우
  • 직접 예외 처리

1) try ~ catch

  • try{ } : 예외가 발생할 수 있는 로직
  • catch( ){ } : 해당 타입의 예외가 발생했을 때 처리할 로직

 

2) finally

  • 예외 발생 여부와 관계없이 무조건 실행할 로직
try {

	// 예외가 발생할 수 있는 로직
	
} catch(Exception e){

 	// 예외가 발생했을 때 실행할 문장
 
}finally{
	// 예외 발생 여부와 관계없이 무조건 실행할 로직
}

 

3. 여러 예외 처리하기

1) 다중 catch 블록

  • catch블록 여러개 사용
  • 하위 클래스 예외가 상위클래스 예외보다 먼저 catch 블록의 인자로 선언 (순서가 중요)

 

2) 멀티 캐치(Multi-catch)

  • 하나의 catch 블록에 다수의 에외 처리 가능
  • 서로 상속 관계가 없어야함. (있으면 부모 예외 클래스로 하면되니까)
  • Java 7 버전부터 사용
try {

	// 예외가 발생할 수 있는 로직
	
} catch(Exception1 | Exception2 e){

 	// 예외가 발생했을 때 실행할 문장
 
}finally{
	// 예외 발생 여부와 관계없이 무조건 실행할 로직
}

 

4. 예외 종류

모든 예외 클래스의 최상위 예외 클래스는 Exception 클래스

1) Checked Exception

  • 반드시 예외 처리를 해줘야 컴파일 수행
  • unchecked exception을 제외한 모든 예외들

 

2) Unchecked Exception

  • 예외 처리 하지 않아도 컴파일 수행
  • 실행시 예외 발생하면 프로그램 비정상 종료됨
  • RuntimeException과 그 하위 예외 클래스
⚠️ 자주 발생하는 Unchecked Exception
- ArithmethicException : 일반적으로 정수를 0(zero)로 나눗셈 하는 경우
- NullPointerException : 인스턴스를 만들기 전에 객체나 메서드에 접근하는 경우
- ArrayIndexOutOfBoundException : 배열의 인덱스를 벗어난 요소에 접근하는 경우

 

사용자 정의 예외

  • Exception 클래스나 그 하위 클래스를 상속받아 정의한 프로그래머가 정의한 예외 클래스

 

5. 예외 던지기 throws / 예외 발생시키기 throw

1) throws

  • 메서드를 호출한 곳으로 예외가 발생했음을 알리는데 사용
  • 메서드 선언부에 throws 절 사용
  • 예외 상황이 여러 개 있는 경우 콤마(,)로 구분하여 나열
  • main() 메서드에서 throws 하는 것은 예외처리를 JVM에 넘기겠다는 의미
modifier return-type methodName() throws Exception1, Exception2 ...{
	method-body;
}

 

2) throw

  • 예외를 발생시키기 위해서 사용
  • 주로 if 블록 등 조건문 안에서 사용
throw new Exception("message"); // Exception 클래스면됨.
  • 내가 예외를 발생시키고 내가 잡지 않도록 구현
  • 일반적으로 예외를 발생시키는 이유는 호출한 사람이 처리하도록 하기 위함.

 

6. 메서드 재정의와 throws

  • throws 로 선언된 메서드를 재정의 할때
  • 재정의하는 메서드는 부모클래스의 메서드에서 throws한 예외가 아닌 새로운 예외는 throws 불가
  • 부모가 throws한 예외 클래스도 자식이 throws한 예외 클래스와 같거나 상위 예외 클래스라는 의미.
class Parent{
	void method() throws IOException{ ... }
}

class Child extends Parent{
	
// IOException가 SQLException의 상위 클래스가 아니라서 불가능.
	@Override
	void method() throws SQLException{ ... } // 컴파일 에러 

// IOException가 FileSystemException의 상위 클래스라 가능.
	@Override
	void method() throws FileSystemException{ ... }
}
⚠️ Association 연관관계
- 열린 화살표로 표현
- 상대 객체가 멤버로 정의된다.
- A → B : B객체가 A클래스의 멤버로 정의됨.

 

⚠️ 인터페이스에서 throws는 지양!
- 일반적으로 인터페이스에서는 throws를 사용하지 않는 것이 옳다.
- 구현 클래스에서 서로 다른 혹은 같은 에러를 똑같이 처리한다고 했을

 

⚠️ 스프링 MVC에서 예외 처리
- 일반적으로 Service에선 try catch를 잘 사용하지 않는 것이 권장된다.
- 하지만 throws 하지 않은 Service 인터페이스, 인터페이스를 구현한 Service 클래스, Repository가 있을때 , Repository에서 예외가 발생한 경우 Service클래스에서 try catch로 발생한 예외를 바꾸기도 한다.
// 예시
// Respository에서 발생한 예외는 RuntimeException이나 그 하위 예외 클래스임
class Service {
	Repository repo = new Repository();
	
	try{
		repo.selectAll();
	}catch(SQLException e){
		throw new RuntimeException(); 
	}
}

 

8. 자원관리 자동화

  • try문 뒤에 괄호를 치고, 변수를 선언하면 try가 끝날때 해당 변수를 자동으로 close를 호출
  • 하지만 try()에 선언한 변수는 try 블록에서만 사용가능
public class AutoResouceCloseExample {
	public static void main(String[] args) {
		try(FileInputStream	in = new FileInputStream("a.txt")) {
			System.out.println("read data :	" +	in.read());
		}catch(IOException ex) {
			System.out.println("예외처리합니다.");
			System.out.println(ex.toString());
		}
}

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기