[Java]예외 처리

Devlog·2024년 3월 25일

Java

목록 보기
23/41

✔️ 예외 처리 코드

- try-catch-finally 블록
: 생성자 내부와 메소드 내부에서 작성되어
  일반 예외와 실행 예외가 발생할 경우
  예외 처리를 할 수 있도록 해줌

try {
	예외 발생가능 코드
} catch(예외클래스 e) {
	예외 처리
} finally {
	/*생략 가능*/
	//예외 발생 여부와 상관없이
	//항상 실행할 내용이 있을 경우에만
	//finally 블록을 작성하면 됨
	항상 실행;
}

: Class.forName() 메소드는 매개값으로 주어진
  클래스가 존재하면 Class객체를 리턴하지만,
  존재하지 않으면 ClassNotFoundException을 발생시킴

👩‍💻 일반 예외 처리
public class TryCatchFinallyExample {
	public static void main(String[] args) {
		
		try {
			Class clazz = Class.forName("java.lang.String2");
		} catch(ClassNotFoundException e){
			System.out.println("클래스가 존재하지 않습니다.");
		}
	}
}

💻 결과
클래스가 존재하지 않습니다.

→ java.lang.String2 클래스가 존재하지 않기 때문에
   예외가 발생함

→ ArrayIndexOutOfBoundsException이나 NumberFormatException과
  같은 실행 예외는 컴파일러가 예외 처리 코드를 체크하지 않기 때문에
  이클립스에서도 빨간 밑줄이 생기지 않음

👩‍💻 실행 예외 처리
public class TryCatchFinallyRuntimeExceptionExample {

	public static void main(String[] args) {
		String data1 = null;
		String data2 = null;
		try {
			data1 = args[0];
			data2 = args[1];
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
			return;
		}
		
		try {
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2
					+ "=" + result);
		} catch(NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}
	}

}

💻 결과
실행 매개값의 수가 부족합니다.

✔️ 예외 종류에 따른 처리 코드

- 다중 catch
: try 블록 내부에는 다양한 예외가 발생할 수 있음
  이럴경우, 다중 catch블록을 작성해야함

try {

} catch(예외클래스 e) {
	예외처리1
} catch(예외클래스 e) {
	예외처리2
}

: catch 블록이 여러 개라 할지라도
  단 하나의 catch블록만 실행됨
→ try블록에서 동시 다발적으로 예외가 발생하지 않고,
  하나의 예외가 발생하면 즉시 실행을 멈추고
  해당 catch블록으로 이동하기 때문

👩‍💻 다중 catch
public class CatchByExceptionKindExample {

	public static void main(String[] args) {
		try {
			String data1 = args[0];
			String data2 = args[1];
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 + "=" + result);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
		} catch (NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}
	}
	
}
💻 결과
실행 매개값의 수가 부족합니다.
다시 실행하세요.

- catch 순서
: 다중 catch 블록을 작성할 떄는
  상위 예외 클래스가 하위 예외 클래스보다 아래 있어야함

- 잘못된 코딩 예
try {
	ArrayIndexOutOfBoundsException 발생
	
	Number FormatException 발생
} catch(Exception e) {
	에외 처리1
} catch(ArrayIndexOutOfBoundsException e){
	예외 처리2
}

→ ArrayIndexOutOfBoundsException과
   NumberFormatException은 모두 Exception을
  상속값을 받기 때문에 첫번째 catch블록만 선택되어 실행됨

→ 두 번째 catch 블록은 어떤 경우에라도 실행되지 않음

- 올바른 코딩 예

try {
	ArrayIndexOutOfBoundsException 발생
	
	Number FormatException 발생	
} catch(ArrayIndexOutOfBoundsException e) {
	예외 처리1
} catch(Exception e) {
	예외 처리2
}

→ try 블록에서 ArrayIndexOutOfBoundsException이 발생하면
  첫 번째 catch블록을 실행하고, 그 밖의 다른 예외가 발생하면
  두 번째 catch블록을 실행함
👩‍💻 catch 블록의 순서
public class CatchOrderExample {
	public static void main(String[] args) {
		try {
			String data1 = args[0];
			String data2 = args[1];
			int value1 = Integer.parseInt(data1);
			int value2 = Integer.parseInt(data2);
			int result = value1 + value2;
			System.out.println(data1 + "+" + data2 +
					"=" + result);
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("실행 매개값의 수가 부족합니다.");
		} catch(Exception e) {
			System.out.println("실행에 문제가 있습니다.");
		} finally {
			System.out.println("다시 실행하세요.");
		}
	}
}

💻 결과
실행 매개값의 수가 부족합니다.
다시 실행하세요.

✔️ 예외 떠넘기기

: 메소드를 호출한 곳으로 예외를 떠넘길 수도 있음
: 이떄 사용하는 키워드가 throws임

- throws 키워드

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

: 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은
  예외를 호출한 곳으로 떠넘기는 역할
: throws 키워드 뒤에는 떠넘길 예외 클래스를
  쉼표로 구분해서 나열해주면 됨

리턴타입 메소드이름(매개변수, ···) throws Exception {
}

: throws Exception만으로도 모든 예외를 간단히
  떠넘길 수도 있음

: thorws 키워드가 붙어 있는 메소드는
  반드시 try 블록 내에서 호출되어야 함 그리고
  catch 블록에서 떠넘겨 받은 예외를 처리해야함

ex)
throws 키워드가 있는 method2()를
method1()에서 호출하는 방법

public void method1() {
	try {
		method2();
	} catch(ClassNotFoundException e) {
		//예외 처리 코드
		System.out.println("클래스가 존재하지 않습니다.");
	}
}

public void method2() throws ClassNotFoundException {
	Class clazz = Class.forName("java.lang.String2");
}

- method1()에서도 try-catch 블록으로 예외를 처리하지 않고
  다음과 같이 throws 키워드로 다시 예외를 떠넘길 수 있음
- 그러면 method1()을 호출하는 곳에서 
  try-catch블록을 사용해서 예외를 처리해야함

public void method1() throws ClassNotFoundException {
	method2();
}
👩‍💻 예외 처리 떠넘기기
버전1)
public class ThrowsExample {

	public static void main(String[] args) {
		try {
			findClass();
		} catch(ClassNotFoundException e) {
			System.out.println("클래스가 존재하지 않습니다.");
		}
	}
	
	public static void findClass() throws ClassNotFoundException {
		Class clazz = Class.forName("java.lang.String2");
	}
	
}

💻 결과
클래스가 존재하지 않습니다.

버전2)
public static void main(String[] args) throws ClassNotFoundException {
	findClass();
}main()메소드에서도 throws 키워드를 사용해서 예외를 떠넘길 수 있음
결국 JVM이 최족적으로 예외 처리를 하게 됨
JVM은 예외의 내용을 콘솔에 출력하는 것으로 예외 처리함

0개의 댓글