Java 예외(Exception)

zzZ·2022년 5월 21일
0

예외 (Exception)

프로그램을 짤 때 여러 오류가 날 수 있다.
이러한 오류를 일단 무시하고 싶을수도 있고 적절한 처리를 필요로 할 때 자바 에서는 이러한 예외를 처리할 수 있다.

예를들어 아래와 같은 코드를 보자

public class ExceptionApp {
	public static void main(String[] args) throws ArithmeticException {
		System.out.println(1);
		System.out.println(2/0); // Run-Time Exception ArithmeticException
		System.out.println(3); 
	}
}

2/0을 하는 연산에서 자바는 예외로 처리한다 이 경우 ArithmeticException

예외 처리

try-catch

public class ExceptionApp {
	public static void main(String[] args)  {
		System.out.println(1);
		int[] scores = {10, 20, 30};

		try {
			System.out.println(2);
			System.out.println(scores[3]); //ArrayIndexOutOfBoundsException
			// 여기까지 실행 -> catch(ArrayIndexOutOfBoundsException e)문으로 이동
			System.out.println(3);
			System.out.println(2/0); //ArithmeticException
			System.out.println(4);
		} catch(ArithmeticException e) {
			System.out.println("잘못된 계산이네요.");
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("없는 값을 찾고 계시네요 ^^");
		}		
		System.out.println(5); 
	}
}

try catch 문으로 예외를 처리 가능하다
위의 코드에서 try문 내부에는 예외가 일어날 코드를 넣어주고
catch문의 괄호안에 인자로 예외 객체를 선언하고 (이때 e는 변수이다)
catch문 내부에 예외상황에서 실행할 코드를 입력한다.

위의 try 내부에서 exception이 발생하면 바로 try문을 빠져나와 해당하는 catch를 실행한다
(System.out.println(3); System.out.println(2/0); System.out.println(4);은 실행되지 않음)

예외의 우선순위(상속관계)

위의 코드에서 ArithmeticExceptionArrayIndexOutOfBoundsException
은 모두 RuntimeException을 상속 받는다 그리고 그 RuntimeExceptionException을 상속받는다.
그래서 위의 코드를 Exception 클래스를 이용해 포괄적으로 처리 가능하다.

catch (Exception e) {
			System.out.println("뭔가 이상합니다. 오류가 발생했습니다. ");
		}	

catch문 변수

지금까지 사용했던 catch의 e는 변수이다.(인스턴스)
자바에서 예외들의 인스턴스를 활용해 예외에 관한 원인을 할 수 있다.

getMessage

catch문에서 e.getMessage() 메소드를 활용하면 예외 상황에 대한 정보를 확인가능하다.

printStackTrac

catch문에서 e.printStackTrace()메소드를 활용하면 에러 메세지를 보이도록 한다.

public class ExceptionApp {
    public static void main(String[] args) {
        System.out.println(1);
        try {
            System.out.println(2/0);
        }catch (ArithmeticException e){
            System.out.println("계산이 이상한데?"+e.getMessage());
            e.printStackTrace();
        }
        System.out.println(3);
    }
}

출력결과:
1
계산이 이상한데?/ by zero
3
java.lang.ArithmeticException: / by zero
at ExceptionApp.main(ExceptionApp.java:5)

checked Exception & unchecked Exception

위 사진에서 Exception 자식으로 RuntimeException은 unchecked Exception이라 하고, 그 나머지는 checked Exception(IOException은 input과 ouput에 관한 exception)이라 한다.

unchecked Exception

unchecked Exception은 따로 예외처리를 하지 않아도 컴파일 해서 실행 할 수 있다.

checked Exception

그러나 checked Exception은 예외처리를 하지 않으면 컴파일이 되지 않는다

Resource 다루기

자바를 통해 작업을 할 때 프로그램 외부의 자원(Resource)에 접근해서 작업을 진행할 수 있다.
대표적인 resource로는 파일, 네트워크, 데이터베이스 등이 있다.
이런 resource들을 다룰때는 오류나 예외가 많이 발생할 수 있다.
resource를 붙잡고 난 뒤 작업을 끝내면 resource를 놓아주는 작업이 필요하다
이때 close()메소드를 사용한다.

예외를 잡을 때 finally 문을 이용해서 resource를 놓아주는 작업이 가능 하지만
Java SE 7부터 try-with-resource문을 활용해 자원관리를 더 단순하게 할 수 있게 되었다.

파일을 열고 닫는 작업을 코드로 보면

import java.io.FileWriter;
import java.io.IOException;

public class TryWithResource {

	public static void main(String[] args) {
		try (FileWriter f = new FileWriter("data.txt")) {
			f.write("Hello");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

try문에 괄호를 추가해 resource 객체를 넣어준다.
위와 같이 코드를 짜면 생성된 인스턴스가 자동으로 종료되기 때문에 따로 f.close()같은 메소드를 다룰 필요가 없다.

throw Exception

지금까지 예외를 try catch로 예외를 처리했다. 예외를 처리하는것도 좋지만 메소드 내부에서 처리하려면 시간과 비용이 들 수 있다. 그래서 메소드 자체에서 예외를 발생시킬 수 있다.
폭탄돌리기처럼 우리가 직접 예외를 처리하기보다 메소드를 사용할 누군가가 처리해주기를 바라는것과 같다.

import java.io.FileWriter;
import java.io.IOException;

public class ThrowException {

	public static void main(String[] args) throws IOException {
		FileWriter f = new FileWriter("./data.txt");
		f.write("Hello");
		f.close();
	}

}

main메소드에서 throws IOException 으로 메소드 자체에서 예외처리

0개의 댓글