Java공부(코딩)

코딩초보의 자바(Java)공부 21일차 { 예외처리 }

동곤일상 2025. 1. 3. 16:33
반응형
오늘은 자바의 예외처리에
대해서
다뤄보겠슴다!!

예외 계층

자바의 예외 처리는 다음 키워드를 사용한다.

`try` , `catch` , `finally` , `throw` , `throws`

 

예외를 다루기 위한

예외처리용 객체를 제공

`Object` : 자바에서 기본형을 제외한 모든 것은 객체다. 예외도 객체이다. 모든 객체의 최상위 부모는 `Object`

이므로 예외의 최상위 부모도 `Object` 이다.

 

`Throwable` : 최상위 예외이다. 하위에 `Exception` `Error` 있다.

 

`Error` : 메모리 부족이나 심각한 시스템 오류와 같이 애플리케이션에서 복구가 불가능한 시스템 예외이다. 애플

리케이션 개발자는 예외를 잡으려고 해서는 안된다.

 

`Exception` : 체크 예외

애플리케이션 로직에서 사용할 있는 실질적인 최상위 예외이다.

`Exception` 하위 예외는 모두 컴파일러가 체크하는 체크 예외이다. `RuntimeException`

외로 한다.

 

`RuntimeException` : 언체크 예외, 런타임 예외

컴파일러가 체크 하지 않는 언체크 예외이다.

 

`RuntimeException` 자식 예외는 모두 언체크 예외이다.

`RuntimeException` 이름을 따라서 `RuntimeException` 하위 언체크 예외를 **런타임 예외**

많이 부른다. 여기서도 앞으로는 런타임 예외로 종종 부르겠다

 


예외 기본 규칙


체크 예외

`Exception` 하위 예외는 모두 컴파일러가 체크하는 체크 예외이다.

`RuntimeException` 예외로한다.

 

체크 예외는 잡아서 처리하거나, 또는 밖으로 던지도록 선언해야한다. 그렇지 않으면 컴파일 오류가 발생한다.

public class MyCheckedException extends Exception{
	public MyCheckedException(String message) {
		super(message);
	}
	//예외 클래스를 만들려면 예외를 상속 받으면 된다.
	//`Exception` 을 상속받은 예외는 체크 예외가 된다.

}
public class Client {
	public void call() throws MyCheckedException{
		throw new MyCheckedException("ex");
	}

}

throw 예외` 라고 하면 새로운 예외를 발생시킬 있다. 예외도 객체이기 때문에 객체를 먼저

`new` 생성하고예외를 발생시켜야 한다.

 

`throws 예외` 발생시킨 예외를 메서드 밖으로 던질 사용하는 키워드이다.

`throw` , `throws` 차이에 주의하자

 

public class Service {
	
	Client client = new Client();
	
	public void callCatch() {
//		예외를 잡아서 
//		처리하는코드
		try {
			client.call();
			
		} catch (MyCheckedException e) {
			System.out.println("예외 처리 : "+e.getMessage());
		}
		System.out.println("정상 흐름");
		
	}
	//예외를 잡지않고 던지는 코드
	public void callThrow() throws MyCheckedException{
		client.call();
	}

}

 

예외를 잡아서 처리 -main

public class CheckedMain {
	public static void main(String[] args) {
		Service service = new Service();
		System.out.println("예외를 잡아서 처리");
		service.callCatch();
		System.out.println("정상종료");
	}
}

예외를 잡아서 처리

예외 처리 : ex

정상 흐름

정상종료

 

`service.callCatch()` 에서 예외를 처리했기 때문에 `main()` 메서드까지 예외가 올라오지 않는다.

`main()` 에서 출력하는 "정상 종료" 문구가 출력된 것을 확인할 있다.

실행 순서를 분석해보자.

1. `main()` `service.callCatch()` `client.call()` **[예외 발생, 던짐]**

2. `main()` `service.callCatch()` **[예외 처리]** `client.call()`

3. `main()` **[정상 흐름]** `service.callCatch()` `client.call()`


예외를  처리하지않고 던지기-main

public class CheckedThrowMain {

public static void main(String[] args) {

Service service = new Service();

System.out.println("예외를 처리 x");

service.callThrow();

System.out.println("정상종료");

}}

Exception in thread "main" java.lang.Error: Unresolved compilation problem:

Unhandled exception type MyCheckedException

 

at lang/exception.basic.checked.CheckedThrowMain.main(CheckedThrowMain.java:7)

 

Service.callThrow()` 안에서 예외를 처리하지 않고, 밖으로 던졌기 때문에 예외가 `main()` 메서드까지

라온다.

 

실행 순서를 분석해보자.

1. `main()` `service.callThrow()` `client.call()` **[예외 발생, 던짐]**

2. `main()` `service.callThrow()` **[예외 던짐]** `client.call()`

3. `main()` **[예외 던짐]** `service.callThrow()` `client.call()`

 

체크 예외를 처리할 없을 때는 `throws` 키워드를 사용해서,

`method() throws 예외` 같이 밖으로 던질예외를 필수로 지정해주어야 한다.

public void callThrow() throws MyCheckedException{

client.call();

}

여기서는 `MyCheckedException` 밖으로 던지도록 지정해주었다

 

체크 예외는 잡아서 직접 처리하거나 또는 밖으로 던지거나 둘중 하나를 개발자가 직접 명시적으로 처리해야한다.

체크 예외는 `try ~ catch` 잡아서 처리하거나

또는

`throws` 지정해서 예외를 밖으로 던진다는 선언을

필수로 해주어야 한다.

 

정리**

체크 예외는 잡아서 직접 처리하거나 또는 밖으로 던지거나 둘중 하나를 개발자가 직접 명시적으로 처리해야한다. 그렇

않으면 컴파일 오류가 발생한다.

 


언체크 예외

`RuntimeException` 하위 예외는 언체크 예외로 분류된다

언체크 예외는 체크 예외와 기본적으로 동일하다.

 

차이가 있다면 예외를 던지는 `throws` 선언하지 않고, 생략

있다. 생략한 경우 자동으로 예외를 던진다

public class MyUncheckedException extends RuntimeException{
	public MyUncheckedException (String message) {
		super(message);
	}
}
public class Client {
	public void call() {
		throw new MyUncheckedException("ex");
	}
}
public class Service {
	Client client = new Client();
	
	public void callCatch() {
		try {
			client.call();
			
		} catch (MyUncheckedException e) {
			System.out.println(e.getMessage());
		}
		System.out.print("정상 로직");
	}
//	예외를 잡지 않아도된다
//	자연스럽게 상위로 넘어감.
//	체크예외와 다르게 throws선언 안해도 됨
	public void callThrow() {
		client.call();
	}
}
public class UncheckedMain {
	public static void main(String[] args) {
		Service service = new Service();
		service.callCatch();
		System.out.println("정상종료");
	}
}

ex

정상 로직

정상종료

 

체크예외와 같은 출력이 나오는것을 확인

public class UncheckedThrowMain {

public static void main(String[] args) {

Service service = new Service();

service.callThrow();

System.out.println("정상종료");

}}

Exception in thread "main" exception.basic.unchecked.MyUncheckedException: ex

at lang/exception.basic.unchecked.Client.call(Client.java:5)

at lang/exception.basic.unchecked.Service.callThrow(Service.java:19)

at lang/exception.basic.unchecked.UncheckedThrowMain.main(UncheckedThrowMain.java:6)

 

언체크 예외는 체크 예외와 다르게 `throws 예외` 선언하지 않아도 된다.

그대로 **컴파일러가 이런 부분을 체크하지 않기 때문에 언체크 예외**이다

 

**정리**

체크 예외와 언체크 예외의 차이는 예외를 처리할 없을 예외를 밖으로 던지는 부분에 있다.

부분을 필수로 선언해야 하는가 생략할 있는가의 차이다.