[Java] 예외 처리 (1)

우쓰·2023년 11월 3일
0

Java

목록 보기
3/10

Content

예외란?

  • 잘못된 사용 또는 코딩으로 인한 오류인데 예외 처리를 통해 실행 상태를 유지할 수 있다.

일반 예외(Exception)

  • 컴파일러가 예외 처리 코드 여부를 검사하는 예외
  • 처리 해주지 않으면 컴파일 오류가 발생한다.

실행 예외(Runtime Exception)

  • 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외를 말한다.

예외 처리 코드

public class ExceptionHandlingExample2 {
  public static void printLength(String data) {
    try {
      // 예외 발생 예상되는 코드
      int result = data.length();
      System.out.println("문자 수 : " + result ); 
    } catch (NullPointerException e) {
      // 예외 발생시 실행 
      e.printStackTrace();
      // 또는 System.out.println(e.getMessage())
    } finally {
      // 항상 실행
      System.out.println("[마무리 실행]\n");
    }
  }

  public static void main(String[] args) {
    System.out.println("[프로그램 실행]");
    printLength("This is Java");
    printLength(null);
    System.out.println("[프로그램 종료]");
  }
}

e.printStackTrace() 로 처리하였을 때 콘솔

[프로그램 실행]
문자 수 : 12
[마무리 실행]

[마무리 실행]

[프로그램 종료]
java.lang.NullPointerException: Cannot invoke "String.length()" because "data" is null
	at ExceptionHandlingExample2.printLength(ExceptionHandlingExample2.java:4)
	at ExceptionHandlingExample2.main(ExceptionHandlingExample2.java:16)

System.out.println(e.getMessage()) 로 처리하였을 때 콘솔

[프로그램 실행]
문자 수 : 12
[마무리 실행]

Cannot invoke "String.length()" because "data" is null
[마무리 실행]

[프로그램 종료]

리소스 자동 닫기

리소스 : 데이터를 제공하는 객체
사용할때 열고 사용이 끝난 뒤에는 닫아야 한다.

try-with-resources

AutoCloseable 인터페이스를 구현해서 close() 메소드를 오버라이딩 하면
try 블록에서의 예외 발생과 관계없이 close() 메소드가 실행된다.

예제

  • AutoCloseable 구현 클래스
public class MyResource implements AutoCloseable {

  private String name;

  public MyResource(String name) {
    this.name = name;
    System.out.println("[MyResource(" + name + ") 열기]");
  }

  public String read1() {
    System.out.println("[MyResource(" + name + ") 읽기]");
    return "100";
  }

  public String read2() {
    System.out.println("[MyResource(" + name + ") 읽기]");
    return "abc";
  }

  @Override
  public void close() throws Exception {
    System.out.println("[MyResource(" + name + ") 닫기]");
  }
}
  • 메인
public class TryWithResourceExample {

  public static void main(String[] args) {
    try (MyResource res = new MyResource("A")) {
      String data = res.read1();
      int value = Integer.parseInt(data);
    } catch (Exception e) {
      System.out.println("예외 처리" + e.getMessage());
    }

    System.out.println();

    try (MyResource res = new MyResource("A")) {
      String data = res.read2();
      // NumberFormatException 발생
      int value = Integer.parseInt(data);
    } catch (Exception e) {
      System.out.println("예외 처리" + e.getMessage());
    }
    System.out.println();

    MyResource res1 = new MyResource("A");
    MyResource res2 = new MyResource("B");
    try (res1; res2) {
      String data1 = res1.read1();
      String data2 = res2.read2();
    } catch (Exception e) {
      System.out.println("예외 처리: " + e.getMessage());
    }
  }
}
  • 콘솔
[MyResource(A) 열기]
[MyResource(A) 읽기]
[MyResource(A) 닫기]

[MyResource(A) 열기]
[MyResource(A) 읽기]
[MyResource(A) 닫기]
예외 처리For input string: "abc"

[MyResource(A) 열기]
[MyResource(B) 열기]
[MyResource(A) 읽기]
[MyResource(B) 읽기]
[MyResource(B) 닫기]
[MyResource(A) 닫기]

I Learned

만약 try 블록에서 여러개의 Exception이 발생한다면?

catch블록이 여러개라도 catch블록은 하나만 실행된다
왜냐하면, 동시 다발적으로 예외가 발생하지 않으며 하나의 예외가 발생하면 즉시 try블록에서의 실행을 멈추고 catch블록으로 가기 때문이다.

public class ExceptionHandlingExample {

  public static void main(String[] args) {
    String[] array = {"100", "1oo"};

    for (int i = 0; i < array.length; i++) {
      try {
        int value = Integer.parseInt(array[i]);
        System.out.println("array[" + i + "]" + value);
      } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("배열 인덱스가 초과됨" + e.getMessage());
      } catch (NumberFormatException e) {
        System.out.println("숫자로 변환할 수 없음" + e.getMessage());
      }
    }
  }
}

예외 처리 시 주의해야되는 것!

처리해야 할 예외 클래스들이 상속관계일때 하위 클래스를 먼저 catch 해주어야 한다

0개의 댓글