[Java] 예외 처리

조혜은·2025년 7월 4일

Java

목록 보기
1/10

예외 처리

예외처리의 기본 = 로깅. 기록하는 것. 에러가 발생했을 때의 상태를 저장해 분석.

프로그램 오류 = 잘못된 방향으로 흘러가는 것.

  • 컴파일 에러 : 컴파일 시에 발생하는 에러
  • 런타임 에러 : 실행 시에 발생하는 에러
  • 논리적 에러: 실행은 되지만 의도와 다르게 동작하는 것.

컴파일 = 사전 예방

컴파일러가 점점 똑똑해지고 있음. 엄격하게.

.java → 컴파일 → .class

실행 중 발생할 수 있는 오류(런타임 에러)

  • 에러(error) : 심각 - 포기 → OOME(OutOfMemoryError), StackOverflowError
  • 예외(exception) : 덜심각 - 처리
    • IOException : 필수 처리
    • ClassNotFounException
    • RunException : 선택 처리. 주로 프로그래머의 실수에 의해 발생.
      • ArithmeticException(산술연산)
      • ClassCastException(형변환) → 지네릭스 사용
      • NullPointerException(null) → Optional 사용
      • IndexOutOfBoundsException(배열) → List, Vector 사용

모든 예외의 최고 조상 = Exception

예외 처리하기

  • 정의 : 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것.
  • 목표 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것.

try-catch문

try {
		// 예외가 발생할 가능성이 있는 문장.
} catch (Exception1 e1){
		// 에러 처리 
} catch (Exception2 e2){
		// 에러 처리
}
- if문임. try-catch 중첩 가능.
- 같은 이름의 참조변수 사용 불가.

JVM이 에러 출력해줌.

catch블럭

  • () - 처리하려는 예외와 같은 타입의 참조변수 선언
  • {} - 예외가 발생했을 때 실행될 문장들.

예외가 발생하면 예외 객체가 만들어짐.(해당 예외 클래스의 인스턴스)

예외객체 - 예외에 대한 정보를 갖고 있음. 예외 보고서. 예외 정보, 메세지.. 이런걸 예외 객체에 담아서 전달. catch블럭에 선언된 참조 변수로 접근 가능.

하나의 메서드 내에 여러 개의 try-catch문 포함 가능.

try{
...
}catch(ExceptionA | ExecptionB e){. // = if(e instanceof ExceptionA || e instanceof ExecptionB)
	e.printStackTrace();
}
합집합 할 때 조상|자손이면 에러남. 조상만 써주는거랑 똑같기 때문.
catch()에서 instanceof연산자로 검사.
해당 결과가 truecatch블럭을 찾으면 블럭 안 내용을 수행하고 빠져나감.

모든 예외는 Exception의 자손들이기 때문에 catch()안에 Exception 타입의 참조변수를 선언하면 어떤 예외가 발생해도 처리 가능.

  • printStackTrace(): 예외 발생 당시 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
  • getMessage(): 발생한 예외 클래스의 인스턴스에 저장된 메세지를 얻을 수 있다.
//printStackTrace()
java.lang.ArithmeticException: / by zero 
	at ExceptionEx8.main(ExceptionEx8.java:7)

//getMessage()
/ by zero

멀티 catch블럭

try{
	...
} catch (ExceptionA | ExceptionB e){
	e.printStackTrace();
}

여러 catch블럭을 하나로 합칠 수 있다. 개수 제한 없음.

|로 연결된 예외 클래스들의 공통 분모인 조상 예외 클래스에 선언된 멤버만 사용 가능.

catch블럭 안에서 ExceptionA의 메서드를 사용하려면 if문으로 해당 예외인지 검사하고 형변환 해서 사용해야함.

if (e instanceof ExceptionA){
	ExceptionA e1 = (ExceptionA)e;
	e1.methodA();
}

예외 발생시키기

throw를 사용해 고의로 예외 발생시킬 수 있음.

  1. new로 발생시키려는 예외 클래스의 객체 생성. Exception e = new Exception(”고의임”);
  2. throw로 예외 발생시킴(예외를 던진다) throw e;

두줄 합치면 → throw new Exception(”고의로 발생시킴”);

예외를 직접 처리하거나 보고시키기.

예외 처리 안하고 예외 발생시키면 컴파일도 안됨.

→ RuntimeException발생시키면 컴파일은 됨, 실행은 비정상종료.

RuntimeException클래스와 그 자손 클래스들에 해당하는 예외는 프로그래머 실수에 의해 발생하는 것들이기 때문에 예외 처리를 강제하지 않음.

  • unchecked예외 : 컴파일러가 예외처리를 확인하지 않는 RuntimeException클래스들
  • checked예외 : 컴파일러가 예외처리를 확인하는 Exception클래스들

예외 처리 안해줬을 때 예외 발생해서 프로그램 죽을 때 나오는 에러 메세지

→ JVM이 출력함. default 예외 처리기.

메서드에 예외 선언하기

실제로 예외를 처리하는 것이 아닌, 해당 메서드를 호출 시 이런 예외가 발생할 수 있으니 이 메서드를 호출하는 쪽에서 예외를 처리해야 한다고 알려주는 것. 떠넘기기.

선언부에 throws를 사용해 예외를 적어주면 됨.

void method() throws Exception1, ... ExceptionN {
	//함수 내용
}
throws Exception 하면 모든 예외가 발생할 수 있다는 뜻.
-> 예외를 선언하면 해당 예외의 자손 예외까지도 발생할 수 있다는 뜻임.
보통 RuntimeException클래스들은 안적음. 꼭 처리해줘야 하는 예외만 선언함.

예외처리 방법

  1. 직접 처리 - try-catch
  2. 보고 - 예외 선언(떠넘기기)
  3. 은폐

파일 이름 예외.

  1. 알아서 처리 - 제목없음
  2. 다시 입력 받기

finally 블럭

예외의 발생여부에 상관없이 실행되어야하는 코드를 포함시킬 목적으로 사용.

try-catch-finally

try {
		// 예외가 발생할 가능성이 있는 문장.
} catch (Exception1 e1){
		// 에러 처리 
} finally {
		// 예외의 발생여부에 상관없이 실행되어야하는 문장.
}

try나 catch문안에 return문이 있어도 finally는 실행됨.

사용자 정의 예외

class MyExceptioon extends Exception {
	//에러코드 추가를 위한 필드 추가
	private final int ERR_CODE;
	
	MyException(String msg, int errCode){
		super(msg); //조상인 Exception클래스의 생성자 호출.
		ERR_CODE = errCode;
	}
	public int getErrCode(){
		return ERR_CODE;
	}
}

기존의 예외클래스는 주로 Exception을 상속받아 checked예외로 작성하는 경우가 많았지만 요즘엔 RuntimeException을 상속받아 작성함. checked예외는 무조건 처리해줘야 하기 때문에 코드가 복잡해짐.

예외 되던지기

예외 처리를 해놓고 다시 던지기.

한 메서드 내에서 발생할 수 있는 예외가 여럿인 경우, 몇 개는 try-catch로 처리. 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 하여 양쪽에서 나눠 처리.

→ 예외를 처리한 후에 인위적으로 다시 발생시키는 방법을 통해 가능. (예외 되던지기)

반환값이 있는 return문의 경우, catch블럭에도 return문이 있어야함.

→ 예외가 발생해도 값을 반환해야하기 때문.

catch블럭 안에 비어있어도 그 블럭안에 들어가면 예외처리 된 걸로 봄.

연결된 예외

  1. 예외를 더 큰단위로 묶어처리. (단순화)
  2. 필수 에러 → 선택 예외

한 예외가 다른 예외를 발생시킬 수 있음.

예외A가 예외B를 발생시켰다면, A를 B의 원인예외라고 함.

0개의 댓글