[Java] 함수 파라미터에 final 키워드를 꼭 붙여야 할까?

final 키워드가 뭔지는 알아 근데 왜 꼭 파라미터 앞에 선언을 해야하는거야?

우아한테크코스 미션을 진행하면서 코치님과 일부 크루들의 코드에서

파라미터에 final 키워드를 항상 붙여주는 것을 보았다.

 

final 키워드 "값의 재할당을 막는다"는 것은 안다.

하지만 왜 꼭 파라미터 앞에 final 키워드를 붙이는 것 일까?

메서드(Method)란?

메서드"객체에 속한 함수"이다.

그리고 함수는 "두 변수 x, y에 대해 x의 값이 변함에 따라 y의 값이 하나씩만 정해질 때, y를 x의 함수"라고 한다.

즉, y = f(x)로 표현할 수 있다.

만약 y = 1000x 라는 함수가 있다고 해보자.

입력 (x) 결과 (y)
2 2000
4 4000

 

x에 입력한 값에 따라 y값이 정해지게 된다.

 

그런데 만약 입력한 값과 전혀 다른 값이 나온다면 (x에 2를 입력했는데 y의 결과가 9000이 나온 경우)

사용자는 무척이나 당황스러울 것이다.

그렇다면 이것은 함수가 아니다.

그래서 final 키워드를 붙이는 거구나...

그렇다 파라미터에 final 키워드를 붙여준다면 이 메서드가 함수라는 것을 보장할 수 있는 수단이라고 할 수 있을 것이다.

또한 3자가 내 코드를 봤을 때 파라미터에 final 키워드가 있다면

메서드 로직에 따라 값이 변경되지 않을 거라는 것이 명시되어 그 코드를 더 읽기 쉬울 것이다.

 

그런데 또 궁금증이 생긴다.

아니 이럴거면 매개변수 재할당을 금지하도록 설계 했으면 안돼..?

문제의 코드

아래는 다리가 중복되서 오면 안된다는 요구사항을 만족시키기 위한 코드로

다리가 연속으로 중복되지 않을 동안 랜덤으로 다리를 생성하는 코드이다.

private LadderBridge generatePoint(LadderBridge now, final LadderBridge before) {
        while (now.equals(LadderBridge.BRIDGE) && before.equals(LadderBridge.BRIDGE)) {
            now = LadderBridge.getByExist(random.nextBoolean());
        }
        return now;
    }
}

이 코드에서는 now라는 매개변수를 받아 이 now가 이전 다리와 동일한 다리라면 매개변수를 재할당해 다시 랜덤한 다리를 만들고 있다.

원래는 매개변수 재할당을 지양해야한다는 것은 알았지만

매개변수 재할당이라는것 자체가 문제가 된다는 것을 전혀인지하고 있지 못했었다.

이 부분에 대해 리뷰를 받았지만 위에서 생긴 매개변수 재할당을 금지하도록 설계 했으면 안돼..? 라는 궁금증이 생겼다.

 

이 궁금증에 대한 리뷰어님의 답변은 다음과 같았다. 👍🏻

결론

필자는 이 이후로 파라미터 앞에 항상 final 키워드를 명시한다.

상속을 사용하지 않을 클래스에도 final 키워드를 명시하는 사람도 있는데

조금 귀찮을지라도 이렇게 선언을 해주는 것이 코드를 보는 사람 입장에서는 더욱 가독성이 좋아질 수 있다고 생각한다.

물론 조직의 컨벤션에 따라 final 키워드를 명시하는지 안하는지는 다를 수 있다.

 

요즘 불변이 기본인 언어와 다르게 자바는 call by value를 채택하고 있어 매개변수를 재할당하는 것은 문제가 없지만

꼭 매개변수의 재할당이 필요할까?

진짜 필요한 경우가 생긴다면, 내부 로직으로 변경되지 않는 파라미터들에는 꼭 final 키워드를 선언해주는 것이 바람직하다 생각한다.

모든 파라미터들에 final이 선언이 안되어 있는데 어떤 파라미터는 내부 로직을 통해 값이 변경되고 어떤 파라미터는 그대로 사용되고..

과연 읽기가 편할까?

또한, 유지보수 관점에서도 한 메서드 내에서 같은 이름의 변수가 로직 진행에 따라 값이 바뀐다면 가독성을 저해할 수 있을 것이다.

 

메서드 추출 시 final 키워드 자동으로 붙이기 설정

Mac 단축키 기준으로 "Cmd + Opt + M" 단축키로 메서드를 추출할 때 파라미터에 자동으로 final 키워드가 붙도록 하는 설정이다.

직접 코드를 작성할 때 final 키워드가 붙도록 하는 설정을 찾지 못했는데 그나마 이 설정을 해 놓으면 좀 더 편한 것 같다..😅