티스토리 뷰

목차

    배경

    이번 글에서는 변수 선언과 할당을 나눠야하는 경우와 그렇지 않은 경우를 다뤄보려고 한다. 사실, 특별한 이유가 없다면 변수 선언과 할당을 나누지 않는 것이 좋다.

    변수 선언과 할당을 나누는 것을 권장하지 않는 이유

    먼저 가독성을 저해하고 코드 이해의 어려움을 초래한다. 코드의 가독성은 항상 중요하다. 내가 작성한 코드는 나 혼자만 보는 것이 아니라 다른사람이 함께 보는 코드이며 결국 개발을 하다보면 코드를 기반으로 의사소통, 문제해결 등 모든 주요 업무를 진행하기 때문이다. 이런 점에서 변수 선언과 할당을 나누면 코드의 흐름을 이해하기 어려워진다. 즉, 다른 사람이 작성한 코드를 읽을 때 해당 변수가 언제 어떻게 초기화되었는지 명확하게 파악하기 어려워진다. 변수 선언과 할당을 나눈다는 것은 결국 초기화를 미룬다는 의미이고, 초기화가 미루어져 있으면 코드를 제대로 이해하기 위해 전체 코드를 계속해서 뒤지고 변수의 사용되는 부분을 찾아야한다. 

     

    두번째로 의도하지 않은 값의 사용을 초래한다. 변수 초기화를 미루게 되면, 초기 값을 설정하지 않은 상태에서 해당 변수를 사용할 수 있다. 이는 NPE(Null Pointer Exception)를 발생시키는 등 예상치 못한 동작을 야기할 수 있다.

    String myValue;
    // ... 중간에 다른 코드 ...
    
    myValue.length(); // NPE 발생

     

    세번째로 변수의 의미를 명확히 전달하지 못한다. 초기화를 나중에 하는 경우, 변수가 실제로 사용되기 전까지는 어떤 역할을 하는지 명확히 알기 힘들어진다.

     

    마지막으로 코드 중복과 유지보수의 어려움을 유발한다. 변수 초기화를 미루다보면 같은 값을 여러 곳에서 초기화해야 할 수 있다. 이는 코드복잡도를 높이고, 값을 사용하거나 변경하는 경우 영향범위를 파악하기 어렵게 만들고 결국 유지보수를 어렵게 한다.

    int result;
    if (condition1) {
        result = computeResult1();
    } else if (condition2) {
        result = computeResult2();
    } else {
        result = defaultResult();
    }
    // ... 중간에 다른 코드 ...
    result = 0; // 같은 변수를 다시 초기화하는 예시

     

     

    변수 선언과 할당을 미루는 경우 코드 가독성을 높이기 위한 방안

    먼저 주석을 활용한다. 주석을 추가하면 변수의 초기화가 나중에 이루어지는 이유와 언제 초기화될 것인지 설명할 수 있을 것이다. 하지만 주석만으로 의도를 충분히 설명하기 어려우므로 주석과 함께 명확한 코드 구조를 사용하는 것이 더 좋을 것이다.

    // 주석을 통해 변수의 초기화가 나중에 일어나는 이유 설명
    
    int result; // 조건에 따라 computeResult1 또는 computeResult2의 결과 할당

     

    두번째로 지역변수를 사용한다. 지연 변수는 특정 블록 내에서만 사용되고 초기화될 수 있으므로 예상치 못한 할당을 방지할 수 있다.

    // 지역 변수 사용
    if (condition1) {
        int result = computeResult1();
        // result 사용
    } else if (condition2) {
        int result = computeResult2();
        // result 사용
    } else {
        int result = defaultResult();
        // result 사용
    }
    // result 변수가 블록 외부에서는 사용되지 않음

     

    마지막으로, 변수를 선언과 동시에 명시적으로 초기화하여 이러한 상황 자체를 방지할 수 있다.

    // 선언과 초기화를 동시에
    int result = 0;
    if (condition1) {
        result = computeResult1();
    } else if (condition2) {
        result = computeResult2();
    } else {
        result = defaultResult();
    }

     

    이처럼 가독성 향상, 유지보수 용이, 사이드 이펙트 방지 등의 목적으로 특별한 경우가 아니라면 변수 선언과 할당을 나누지 않는 것이 권고된다. 이렇게 글을 작성하다보면 그러면 변수 초기화를 미루는 특별한 경우는 뭔데 ? 와 같은 궁금증이 생길 것이다

    변수 선언과 할당을 나눠야하는 경우

    변수 초기화를 미루는 특별한 경우에 해당한다. 먼저 예외 처리의 경우가 있다. 특정 조건이나 예외적인 상황에서만 변수를 초기화해야 할 때 선언을 먼저 하고, 예외적인 상황에서 초기화하는 것이 유용할 수 있다.

    int value; // 초기화를 나중에 수행
    try {
        value = getValueFromExternalSource();
    } catch (Exception e) {
        value = handleException();
    }

     

    변수 초기화를 미뤄야하는 두번째 경우로 Spring 진영에서 많이 사용되는 의존성 주입(Dependency Injection)이 있다.

    public class MyClass {
        private MyDependency dependency;
    
        // 생성자를 통해 의존성 주입
        public MyClass(MyDependency dependency) {
            this.dependency = dependency;
        }
    }

    결론

    일반적으로는 변수를 선언하면서 초기화를 하는 것이 코드의 가독성을 높이고 오류 발생 가능성을 낮출 수 있다. 변수를 미리 선언하고 초기화를 미뤄야 하는 특별한 상황이 아니라면, 선언과 동시에 초기화를 하는 것이 권고된다.

    Comments