티스토리 뷰

Java/Effective Java

[Item69] 예외 기반 반복

ryumodern 2022. 9. 25. 14:45

Item69에서 예외는 진짜 예외 상황에서만 사용하라 말한다.

너무나 당연한 얘기를 왜 한 장에 할당해 설명했을까?

바로 다음과 같은 해괴한 방식으로 작성하는 녀석들이 있기 때문이다

try {
    int i = 0 ;
    while (true) {
        System.out.println(array[i++]);
    }
} catch (ArrayIndexOutOfBoundsException e) {
    // doSomething...
}

 

위 코드의 의도는 array로 선언한 배열의 인덱스를 하나씩 늘려가며 출력하는 것인데

배열의 마지막 요소까지 출력하기 위해 범위를 넘어갈 때 (즉 ArrayIndexOutOfBoundsException이 발생할 때)

catch 블록에서 잡아서 별도의 처리를 하거나 하지 않거나 하는 방식으로 작성한 것이다

for-each loop, for-loop으로 작성하면 아주 간단한데 원래의 의도와 벗어나게 예외를 활용해 흐름을 제어하는 방식이다

올바른 방법을 벗어났기에 나는 사파의 방법이라 부른다

 

사파의 방식을 쓸 것이라면 정파의 방식보다 나은 게 있어야 쓸까 말까 고민이라도 할 텐데 

아래 3가지의 이유로 속도도 느리고 이해할 수 없는 코드가 탄생한다

1. 예외 자체가 다양한 상황에서 사용될 것을 산정하고 만들어진게 아님

2. try-catch block 안에서는 최적화 여지가 줄어듬

3. 많은 JVM 구현체들이 이미 인덱스 마지막 값 처리를 최적화해둠

 

위 코드 블록에서 한술 더 뜨는 위험은 i로 선언한 인덱스를 직접 다룰 때 발생한다

아래처럼 돌려버리면 i는 놀랍게 50도 아니고 51이 나온다

int array = new int[50];
int i = 0 ;

try {
    while (true) {
        System.out.println(array[i++]);
    }
} catch (ArrayIndexOutOfBoundsException e) {
    log.info("i = {}", i);
}

 

인덱스에 대해서는 거의 다 알겠지만 한번 더 짚고 넘어가자, 인덱스는 0부터 시작하니 마지막 인덱스는 49가 된다

i++로 후위 증감 연산을 때려버리니 정상 접근 가능한 마지막 인덱스 49에서부터 살펴보면 된다

i = 49일 때 i++은 50이다, 다시 while 반복 안에서 출력하려 하니 i = 50인 상황이고

ArrayIndexOutOfBoundsException이 터지지만 i++은 이미 처리된 상황이다

이에 관련된 보안 취약점 글이 있었는데 까먹었다, 나중에 찾으면 첨부해야겠다

그 글의 요지는 예외가 터지더라도 메모리 상에서 이미 연산이 수행된 데이터를 조작하는 것이었다

즉, 예외 터트리면 끝이 아니라 그 뒤에 변수에 할당된 값을 이전 값으로 돌려놓거나 or 메모리에서 날려버리는 과정이 필요하다

 

애초에 for-loop, for-each loop은 사용자에게 인덱스 조작을 허용하지 않기에 고민하지 않아도 되는 문제다

다만 이런 문제들에도 불구하고 한 가지 생각해 볼만한 점은 있는 것 같다

무지성 개발만 한다면 for-each 쓰면 되지 하고 끝낼 수 있는데

애플리케이션에서 요구되는 상황을 boundary register의 경계 값 확인으로도 해결할 수 있구나 하는 인사이트를 얻을 수 있다

문제를 푸는 다양한 방법이 있다지만 산업 스파이가 아니라면 예외 기반 반복은 생각지도 말자

특히나 여러 사람이 협업하는 경우에는 더더욱. 정도의 길을 걷고 자바의 도를 깨우치러 가보자

'Java > Effective Java' 카테고리의 다른 글

[Item71] Checked Exception 즐겨보기  (0) 2023.01.30
[Item70] Checked Exception 금지  (0) 2022.11.01
[Item68] 컨벤션 따르기  (1) 2022.09.11
[Item67] 최적화는 나중에  (0) 2022.08.28
[Item66] 자바 네이티브 인터페이스  (0) 2022.08.03
댓글
링크
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday