본문 바로가기
ETC/도서

[자바의 신] 14장. 다 배운 것 같지만, 예외라는 중요한 것이 있어요

by sorryisme 2024. 9. 27.

try catch

package exceptionExample;

public class ExceptionExample {
    public static void main(String[] args) {
        ExceptionExample exceptionExample = new ExceptionExample();
        exceptionExample.arrayOutofBounds();
    }

    public void arrayOutofBounds() {
        int[] intArray = new int[5];
        try {
            System.out.println(intArray[5]);
            System.out.println("this code should run");
        } catch (Exception e) {
            System.err.println("Exception occured");
        }
        System.out.println(" code must run");
    }
}

  • try-catch에서 예외가 발생하지 않을 경우
    • try 내에 있는 모든 문장이 실행되고 try catch 문장 이후 내용이 실행된다
  • try-catch에서 예외가 발생하는 경우
    • try 내에서 예외가 발생한 이후 문장들은 실행되지 않는다
    • catch 내에 문장은 반드시 실행 그 이후 try catch 문장 이후 내용이 실행된다

try-catch에서 적응하기 힘든 변수 선언

  • try 블록 내에서 선언한 변수를 catch 내에서 사용할수 없다
public class ExceptionVariable {
    
    public static void main(String[] args) {
        ExceptionVariable exceptionVariable = new ExceptionVariable();
        exceptionVariable.checkVariable();
    }

    public void checkVariable() {
        int[] intArray = null;

        try {
            intArray = new int[5];
            System.out.println(intArray[5]);
        } catch (Exception e) {
            System.err.println(intArray.length);
        }

        System.out.println("this Code must run");
    }
}

// 출력값 5
  • 하지만 위와 같이 null이라고 지정하더라도 예외가 발생한 순간 이미 배열이 할당된다
  • 그렇기에 catch에서 사용하는 변수는 블록 앞에서 선언해줘야한다

finally

  • 자바에서 예외처리할 때 finally는 어떠한 경우에서도 실행하라는 의미
  • 코드의 중복을 피하기 위해서 필요하다

두개 이상의 catch

package exceptionExample;

public class MultiCatchSample {
    public static void main(String[] args) {
        MultiCatchSample multiCatchSample = new MultiCatchSample();
        multiCatchSample.multiCatch();
    }

    public void multiCatch() {
        int[] intArray = new int[5];
        try {
            System.out.println(intArray[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array Index Out of Bound Exception");
        } catch (Exception e) {
            System.err.println(intArray.length);
        }
    }
}

  • 여러 개의 catch 블록을 만들어서 사용해도 전혀 상관없다
  • 모든 예외의 부모 클래스는 java.lang.Exception 클래스이다

예외의 종류는 세 가지다

  • checked exception
  • error
  • runtime exception 혹은 unchecked exception
    • error와 unchecked exception을 제외한 나머지가 checked exception이다

error

  • 자바 프로그램 밖에서 발생된 에러
    • 서버 디스크 고장
    • 메인보드 고장
  • Error로 끝나면 에러
  • 프로그램 안에서 발생했는지 밖에서 발생했는지
    • Error는 프로세스에 영향을 주고 Exception은 쓰레드에만 영향을 준다

runtime Exception(unchecked Exception)

  • 예외가 발생할 것을 미리 감지 못할 때 발생
    • NullPointException
    • IndexOutofBoundException

모든 예외의 할아버지는 java.lang.Throwable 클래스

  • Exception과 Error의 공통 부모 클래스는 Throwable
  • 많이 사용하는 메소드
    • getMessage() : 예외 메세지를 String 형태로 받는다
    • toString() : 예외 클래스 이름도 같이 제공 받는다
    • printStackTrace() : 예외 메세지 출력하고 호출 관계를 출력해준다
package exceptionExample;

public class ThrowableSample {
    public static void main(String[] args) {
        ThrowableSample throwableSample = new ThrowableSample();
        throwableSample.throwable();

    }

    public void throwable() {
        int[] intArray = new int[5];

        try {
            intArray = null;
            System.out.println(intArray[5]);
        } catch (Throwable t) {
            System.err.println(t.getMessage());
            System.err.println(t.toString());
            t.printStackTrace();

        }

    }
}

난 예외를 던질 거니깐 throws라고 써 놓을게

  • 예외를 발생시킬 수 있다
package exceptionExample;

public class ThrowSample {

    public static void main(String[] args) {
        ThrowSample sample = new ThrowSample();
        sample.throwException(13);

    }

    public void throwException (int number) {
        try {
            if(number > 12) {
                throw new Exception("Number is over than 12");
            }

            System.out.println("Number is " + number);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  • try 블록 내에서 throw라고 예약어를 명시한 후 예외 클래스의 객체를 생성하면 된다
  • 만약에 해당하는 예외가 없다면 발생된 예외는 메소드 밖으로 던져 버린다
  • 이럴때 사용하는 것이 메소드의 throws 구문이다
public void throwException (int number) throws Exception {
	   
	if(number > 12) {
	    throw new Exception("Number is over than 12");
	}
	
	System.out.println("Number is " + number);   
}
  • 호출한 메소드에서 try - catch 묶거나
  • throws로 다시 한 번 처리해야한다

내가 예외를 만들 수 있다구?

  • Error가 아닌 Exception을 처리하는 예외 클래스는 개발자가 임의로 추가해서 만들 수 있다
  • Throwable이나 그 자식 클래스를 상속받아야 한다
  • java.lang.Exception 클래스를 상속 받는 것이 좋다
package exceptionExample;

public class MyException extends Exception {
    public MyException() {
    }

    public MyException(String s) {
        super(s);
    }
}

자바 예외 처리 전략

  • 커스템 예외 클래스의 경우 실행 시 발생할 확률이 높다면 런타임 예외로 만드는 것이 좋다
    • extends RuntimeException
    • try catch로 묶지 않아도 컴파일 시 예외가 발생하지 않는다
    • 하지만 방어코드로서 메소드를 호출하는 곳에서 try catch로 처리해주는 것이 좋다