본문 바로가기
💾 Backend/자바

💖자바 예외‼️ 처리💖

by 정람지 2023. 5. 11.

‼️오류‼️

부정확하거나 유효하지 않은 동작

 

⚠️컴파일 오류 (에러)

프로그램 코드 작성 중 실수로 발생

개발 환경에서 대부분 오류를 알 수 있음 (문법적 오류)

컴파일 오류를 모두 수정해야 프로그램이 실행됨

 

⚠️실행 오류 

실행 중인 프로그램이 의도하지 않은 동작을 하거나 프로그램이 중지되는 오류 

예측하기 어려움

오류 클래스는 Throwable 클래스에서 상속. Error 클래스는 시스템오류를 다루고 Exception 클래스는 예외 클래스를 다룸.

a) 시스템 오류(런타임 에러)

프로그램에서 제어할 수 없는 시스템 오류 

예측 불가 / 정지 불가(강제 프로그램 종료하지 않을 시)

ex) 사용 가능한 동적 메모리 없음, 스텍 메모리의 오버플로우 발생

 

b) 예외⭐️

프로그램에서 제어 가능하므로 예외 처리를 통해 프로그램이 비정상 종료되는 것을 막고자 함.

정상 실행 상태로 돌아갈 수 있음(잡을 시)

예외처리 없이 예외 마주치면 프로그램 종료

ex) 프로그램에서 읽어야 하는 파일이 존재하지 않을 경우, 데이터 전송 시 네트워크 연결이 안 된 경우, 배열 출력 시 배열 요소가 없는 경우 등

예외 클래스. 최상위 Exception 클래스 (많이 사용되는 몇몇 에외 클래스)

 


‼️유명 예외 클래스‼️

 

💖일반(컴파일 체크) 예외💖

예외 처리가 되지 않으면 컴파일 에러 발생

 

 IOException

 

 

입출력 예외

    ✨FileNotFoundException

    시스템에 실제로 존재하지 않는 파일을 읽으려고 할 때 발생

 

✨ClassNotFoundException

 

 

✨interruptedException

 

 

💖실행 예외 RuntimeException💖

컴파일은 통과되는 예외

 

✨NullPointerException✨

null 값을 가지는 객체/변수를 호출할 때 발생

객체 참조가 없는 상태

String a = null;
System.out.print(a.toString());
//null 값 갖는 참조변수로 객체 접근 연산자인 도트(.) 사용했을 때 발생

int arr[]; //new로 힙 메모리에 생성 안함
ar[2] = 4;

 

✨IndexOutOfBoundsException✨

String, 배열 등에서 index 값이 범위를 초과했을 때 발생하는 예외

+ArrayIndexOutOfBoundsException배열에서 인덱스 범위 초과하여 사용할 경우 발생

int arr[] = new int[3];
arr[4] = 5;

 

ClassCastException

타입 변환이 되지 않을 경우 발생 (올바르지 않은 캐스팅 시)

Animal animal = new Dog();
Cat cat = (Cat)animal;
// Cat과 Dog 클래스가 animal 클래스 상속받았을 시 이 코드 ClassCastException
 

ArithmeticException

나누는 수가 0일 경우 발생

 

IllegalArgumentException

적합하지 않거나 적절하지 못한 인자를 메소드에 넘겨주었을 때 발생

 

 

✨NumberFormatException

문자열이 나타내는 숫자와 일치하지 않는 타입의 숫자로 변환 시 발생

String s = "happy";
int n = integer.parseInt(s); //String타입의 숫자를 int타입으로 변환해주는 메서드

 

명품 자바 프로그래밍 교재


‼️예외 처리하기‼️

프로그램 비정상 종료 방지를 위해 필요

예외 발생 시 JVM은 자동으로 발생된 예외 객체를 생성하여 전달함 +. 문자로 인식한 메세지 출력 후 프로그램 수행 도중 중단

일반예외반드시 작성해야 컴파일 가능
실행 예외: 컴파일러가 체크해주지 않으며 개발자 경험에 의해 작성

💖try-catch문💖

  • 자바의 Exception 클래스에 속하는 객체 e catch 블록의 매개변수라고 함
  • 예상되는 문제가 있을 것 같은 문장을 try블록으로 설정
  • catch 블록은 예외별로 여러 개 존재할 수 있으며(다중 예외 처리) , 최상위 예외(exception 등)는 가장 마지막에 위치(앞에 올 시 오류)
  • 상위 클래스의 예외가 하위 클래스의 예외문제 받을 수 있음
  • catch 블록의 코드가 실행된 후 catch 블록 다음에 이어지는 문장을 계속 수행
try{
	//예외가 발생할 수 있는 코드 
}catch(처리할 예외 타입 e){ //해당 예외 객체가 자동으로 생성(throw)되고 전달
	//예외 처리 코드
}

 

✨catch 다중 예외✨

여러 개의 예외의 처리방법이 같을 때

try{
	//예외가 발생할 수 있는 코드 
}catch(처리할 예외 타입1 | 처리할 예외 타입2 e){ 
	//예외 처리 코드
}

 

✨finally✨

  • finally 블록 : 예외 발생과 전달(throw) 여부에 관계없이 항상 실행되는 코드 블록으로 생략가능.
  • 주로 청소용, 마무리용
  • 가급적 의미있는 값 반환하게 하지 않기
try{
	//예외가 발생할 수 있는 코드 
}catch(처리할 예외 타입 e){
	//예외 처리 코드
}finally{
	//항상 수행되는 코드
}

각 {} 안의 필드는 지역변수!

 

 

✨try-with-resource문✨

try(...)에서 선언된 객체들에 대해서 try가 종료될 때 자동으로 자원을 해제해주는 기능

try에서 선언된 객체가 AutoCloseable을 구현하였다면 Java가 try구문이 종료될 때 객체의 close() 메소드를 호출함

어렵

 

 

💖예외 처리 미루기(떠넘기기)💖

throws : catch()와 달리 전달만 함.

예외를 처리하지 않고 미루면, 메서드를 호출하고 사용하는 부분에서 예외 처리를 해야 함

리턴타입 메소드명(매개변수) throws 예외클래스1,예외클래스2,..{
}

//메소드를 호출한 곳에서 예외 처리 (try-catch)

 

💖사용자 정의 예외💖

예외 클래스를 직접 만들어 예외를 발생시키고 예외 처리 코드 구현 가능

 

- 유사한 예외클래스나 가장 상위 클래스인 Exception클래스, 또는 RuntimeException 상속받아 만들기

- 코드에서 예외를 발생시키는 법 throw

class 사용자예외처리 extends Exception{//또는 다른 예외
	//예외처리 코드
    public 사용자예외처리(){} //생성자
    public 사용자예외처리(String 메세지){super(메세지);} //생성자
}
throw new 사용자정의예외();
throw new 사용자정의예외("메시지");
public void 예외날지도모르는메소드() throws 사용자정의예외{
	throw new 사용자정의예외("메시지");
}

//메소드 쓰는곳에서 예외처리하기

💖예외 정보 얻기💖

 

+ Exception 클래스 : 두 개의 생성자  가짐

1. Exception (String s) : 메세지로 예외 객체 생성

2. Exception () : null 문자열로 예외 객체 생성

 

+발생한 Exception 정보를 알아오는 메소드:

String getMessage() : 예외 객체에 저장된 문자열 / null 반환

 

- getMessage()

예외를 발생시킬 때 생성자 매개값으로 메세지 리턴, catch 블럭에서 사용

throw new 사용자정의예외("예외 메세지");

printStackTrace()

예외 발생 코드를 추적한 내용을 모두 콘솔에 출력

프로그램을 테스트하면서 오류 찾을 때 유용하게 활용

 

 

+코드

class 사용자예외처리 extends Exception{
	//예외처리 코드
    public 사용자예외처리(){} //생성자
}

public class Main{

	public 사용자(String 코드){
        //코드
      	 throw new 사용자예외처리();
    }
    
    public static void main(String args[]){
    
    	try{
        	사용자("..");
        }catch(사용자예외처리 e){
        	String 메세지 = e.getMessage();
            
            e.printStackTrace();
        }
        
    }
}

 


‼️코드실습‼️

try-catch-finally

import java.util.*;

class 고양이 extends 동물{
	public void 움직이기() {
		System.out.println("실금살금");
	}
}

//예외처리 
public class Main {

	public static void main(String[] args) {
		
		// int b+1; 문법에러 
		int a = 10 ;
	
		try {
			//0으로나누기 = ArithmeticException
			a /= 0 ;
			
			//배열 인덱스 넘어보기 = ArrayIndexOutOfBoundsException
			int [] ar = new int[10];
			ar[10] = 10;
			
			//없는 객체 사용하기 = NullPointerException
			강아지 dog = null;
			dog.뛰기();
			
			//캐스팅미스 = ClassCastException
			동물 ani = new 동물();
			((고양이) ani).움직이기();
			
			//정수받을 때 문자섞기 = InputMismatchException
			Scanner sc = new Scanner(System.in);
			int num = sc.nextInt();
		}
		catch(ArithmeticException e) {
			System.out.println("0으로 나눌 수 없어요! ");
			a = 0;
		}
		catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("인덱스의 유효범위를 홧잉하게요! ");
		}
		catch(NullPointerException e) {
			System.out.println("강아지를 만들어야 합니다");
		}
		catch(InputMismatchException e) {
			System.out.println("정수를 입력해야 합니다!");
		}
		catch(Exception e) {
			System.out.println("뭔지 모를 예외가 발생! ");
			e.printStackTrace(); // 무슨 예외가 발생했는지 출력 
		}
		finally {
			System.out.println("예외가 발생하든 안 하든 항상 실행 ");
		}
		
		
		System.out.println("프로그램 종료! ");
	}
		
}

throws

import java.util.*;

public class Main {

	public static double divideNum(int a, int b) throws ArithmeticException{
		double result = a/b;
		return result;
	}
	
	static Scanner sc = new Scanner(System.in);
	
	public static void main(String[] args) {
		
		boolean okay = true;
		
		while (okay) {
			System.out.print("정수 2개를 입력:");
			int a = sc.nextInt();
			int b = sc.nextInt();
			
			try {
				double result = divideNum(a,b);
				System.out.println(result);
				okay = false;
				
			}catch(ArithmeticException e) {
				System.out.println("0으로 나누지 마세요!!");
			}
		}
		System.out.println("프로그램 종료");
	}
}


+ 예외 처리를 할 때는 로그 기록을 잘 남겨 코드 수정을 용이하게!

 

+ System.exit(0) 

프로그램 강제종료코드