Content
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
[마무리 실행]
[프로그램 종료]
리소스 자동 닫기
리소스 : 데이터를 제공하는 객체
사용할때 열고 사용이 끝난 뒤에는 닫아야 한다.
AutoCloseable 인터페이스를 구현해서 close() 메소드를 오버라이딩 하면
try 블록에서의 예외 발생과 관계없이 close() 메소드가 실행된다.
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
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 해주어야 한다