아래 테스트들은 모두 성능만 고려하였다. 사내 규약 혹은 사수의 조언이 있다면 그걸 우선시 하는게 맞다.그런게 없다면 아래 기준에 따라 코드 선택을 하는것도 나쁘지 않을것 같다.
모든 테스트는 Java 8을 기준으로 진행하였다.사내 신규 프로젝트가 전부 8로 진행되기도 하였고, 조금 있으면 9가 나오는 상황에서 6,7을 기준으로 작성하는 것이 곧 의미가 없어질 수 있다는 생각이였다.그래서 6,7에서는 조금 다른 결과가 나올지도 모른다는 것을 미리 얘기한다.
회사 혹은 팀이 얼마나 Java를 잘 다루는지는 Exception처리를 어떻게 하고 있는지를 보면 된다라는 말이 있을 정도로 Exception 처리는 모든 Java 개발자에게 중요한 이야기라고 생각한다.
우리가 예외처리를 하는 방법은 다양하다. 모든 것을 throw만 할 수도 있고, 발생할 지점에서 하나하나 try catch 할 수도 있고, 애초에 발생할만한 여지가 있는 경우를 전부 방어코드로 사전방지를 할 수도 있다.
어떤 방식이든 본인만의 혹은 팀만의 규칙이 있을것이다. 다만 각 방식들 간의 성능은 조금씩 차이가 있다. 아래 코드가 모든 것을 결정하는 기준이 될 순 없지만, 추가적으로 고려해볼만한 기준은 될것같다. 예제코드를 보며 각각의 코드를 비교해보겠다.
private void test_throwException() { // i가 홀수일 경우 null pointer exception을 throw 하여 바깥부분에서 catch
list = new ArrayList<>();
for (int i = 0; i < SIZE; i++) {
try {
if (i % 2 != 0) {
throw new NullPointerException();
}
String s = "performance";
list.add(s);
} catch (NullPointerException npe) {
}
}
}
private void test_tryCatch() { // null pointer exception이 발생할 부분인 list.add() 를 try catch로 감싼다.
list = new ArrayList<>();
for (int i = 0; i < SIZE; i++) {
String s = null;
if (i % 2 != 0) {
s = "performance";
}
try {
list.add(s);
list.get(i).indexOf(0); // NPE 강제 발생
} catch (NullPointerException npe) {
}
}
}
private void test_notNull() { // null pointer exception이 발생하지 않도록 방어 코딩
list = new ArrayList<>();
for (int i = 0; i < SIZE; i++) {
String s = null;
if (i % 2 != 0) {
s = "performance";
}
if (s != null) {
list.add(s);
}
}
}
첫번째 코드의 경우 i가 홀수일 경우 null pointer exception을 throw 하여 바깥부분에서 catch하도록 하였다.
두번째 코드의 경우 null pointer exception이 발생할 부분인 list.add() 를 try catch로 감싸도록 하였다.
마지막 코드의 경우 null pointer exception이 발생하지 않도록 방어 코딩을 하였다.
코드에서 직접 NullPointerException을 보내는것(첫번째 예제)과 JVM에서 NullPointerException을 보내는 것(두번째 예제)에는 큰 차이가 난다.
즉, JVM은 필요할때마다 새로 생성하지 않고, 동일한 Exception 객체를 재사용 한다는 것이다.