이번 아이템은 아이템 15에서 다루었던 `클래스의 멤버와 접근권한을 최소화하라`와 취지가 비슷합니다.
지역 변수의 범위를 최소화하면 코드의 가독성이 높아지고 유지보수가 쉬워지며 오류 발생 가능성이 낮아집니다.
지역변수는 가장 처음 쓰일 때 선언하자
- 지역 변수가 초기화된 지점과 사용되는 지점이 멀어질수록 코드의 가독성이 떨어지고 혼란스러워짐.
- 막상 쓰일 시점에 돼서는 해당 지역변수가 무슨 타입이었는지, 무슨 값으로 초기화했는지 기억이 나지 않을 가능성이 높음
- 지역변수를 생각 없이 선언하다 보면 변수가 쓰이는 범위보다 너무 앞서 선언하거나, 다 쓴 후에도 메모리 회수가 되지 않고 여전히 살아있을 확률이 높음
- 지역변수의 범위는 선언된 지점부터 그 지점이 포함한 블록이 끝날 때까지 유효
- 실수로 의도한 범위 앞 혹은 뒤에서 해당 변수를 사용할 경우 끔찍한 결과를 초래할 수 있음
지역변수는 선언과 동시에 초기화하자
- 초기화에 필요한 정보가 충분하지 않을 경우 정보가 충분할 때까지 선언을 미루는 것을 권장
- try-catch-finally 구문에서는 예외
- 변수를 초기화하는 표현식에서 checked exception을 던질 가능성이 있다면 try 블록 내에서 초기화해야 함
- 그렇지 않을 경우 예외가 블록을 넘어 메서드에까지 전파됨


- 반복문은 독특한 방식으로 변수 범위를 최소화
- 반복문에서는 반복 변수의 범위가 반복문의 몸체, 그리고 for 키워드와 몸체 사이의 괄호 안으로 제한
- 따라서 반복 변수의 값을 반복문이 종료된 뒤에도 써야하는 케이스가 아니라면 while문보다는 for문 사용하는 것을 권장
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for (Element e : c) { | |
// 지역변수 e를 사용하는 로직 | |
} | |
for (Iterator<Element> i = c.iterator(); i.hasNext();) { | |
Element e = i.next(); //e와 i로 무언가를 한다. | |
} |
for문이 while문보다 나은 이유
- 반복 변수가 여러개일 경우 실수로 이전 while문에서 쓰인 반복 변수를 사용할 수 있음 (휴먼 에러 발생 가능성)
- 컴파일 시점에는 에러를 파악하기 쉽지 않고 런타임에서 실수를 발견할 확률이 높음
- for문을 포함한 for-each문을 사용하는 경우에는 반복자의 유효범위가 for문의 종료와 함께 끝나기 때문에 이러한 문제를 컴파일 타임에 잡아줌
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List<Integer> list = new ArrayList<>(); | |
List<Integer> list2 = new ArrayList<>(); | |
Iterator<Integer> i = list.iterator(); | |
while (i.hasNext()) { | |
// 비즈니스 로직 | |
} | |
Iterator<Integer> i2 = list2.iterator(); | |
// 실수로 i2가 아닌 i를 쓰는데도 불구하고 컴파일 에러 발생 안함 | |
while (i.hasNext()) { | |
// 비즈니스 로직 | |
} | |
for (Iterator<Integer> i3 = list.iterator(); i3.hasNext(); ) { | |
// 비즈니스 로직 | |
} | |
// 컴파일 에러 발생 | |
for (Iterator<Integer> i4 = list.iterator(); i3.hasNext(); ) { | |
// 비즈니스 로직 | |
} |

메서드를 작게 유지하고 한 가지 기능에 집중하자
- 한 메서드 내에서 여러가지 기능을 처리할 경우 그중 한 기능과 관련된 지역변수라도 다른 기능을 수행하는 코드에서 접근 가능
- 따라서 기능별로 메서드를 쪼개면 위와 같은 상황을 모면할 수 있음
참고
이펙티브 자바
반응형
'JAVA > Effective Java' 카테고리의 다른 글
[아이템 59] 라이브러리를 익히고 사용하라 (0) | 2024.03.17 |
---|---|
[아이템 58] 전통적인 for 문보다는 for-each 문을 사용하라 (0) | 2024.03.16 |
[아이템 56] 공개된 API 요소에는 항상 문서화 주석을 작성하라 (0) | 2024.03.13 |
[아이템 55] 옵셔널 반환은 신중히 하라 (0) | 2024.03.12 |
[아이템 54] null이 아닌, 빈 컬렉션이나 배열을 반환하라 (0) | 2024.03.11 |