final parameter
Method 인자로서 final parameter 를 선언해두는 것을 본 적 있다.
Java 에서 final 키워드는
- 클래스 → 상속을 허용하지 않는 클래스
- 메소드 → 오버라이딩을 허용하지 않는 메소드
- 클래스,인스턴스 변수 → 초기화 이후에 값을 변경할 수 없는 변수임을 명시적으로 나타낸다
- 물론, 이 변수가 “참조변수" 인 경우라면, 해당 객체 내부의 값은 또 변경될 가능성이 존재한다.
를 의미한다.
“인자"는 변수와 같은 의미에서 final 을 사용하는 걸까?
어차피 Java 에서는 “참조값을 전달" 하며, 이 값 자체는 스택에 복사되어올 뿐이다.
따라서 새로운 메소드 호출로 인해 생긴 스택 프레임 상의 값을 변경하는 것은 Caller 에 존재하던 참조 변수의 값을 변경하지는 않는다.
그럼에도 final parameter 를 사용하는 이유가 뭘까?
생각해보니 위의 생각은 “Caller 와 Callee 측에서 값이 일관되게 하는 것” 에서는 final parameter 가 쓸모 없다는 것이라는 것에 초점이 맞춰진 생각이었다.
호출된 메소드의 스택 프레임에서는 parameter 참조값이 변경될 가능성이 존재한다는 것이다
public void solution(String input){
input = "내가 바꿀거얌";
...
}
개발자의 실수던.. 개발자가 순간적으로 엥 input 참조변수를 재사용하면 되겠는데?? 여기에 다른 값 재할당해서 다시 사용할래~~~ 하는 생각에 변경할 가능성이 존재한다.
따라서 아래와 같이 final parameter 를 사용한다면 위와 같은 상황을 방지 할 수 있다
public void solution(final String input) {
input = "내가 바꿀거얌"; // 불가능!!!
...
}
좋은 습관 ?
찾아보니 Caller 가 메소드를 호출할때 전달한 객체(참조값) 외의 값으로 인자를 재할당 하지 않는 것이 좋은 습관일 것이라고 말하고 있다.
그러니까..위의코드를 예시로 들자면, 코드내부에서는 input = … 같은 구문이 등장해선 안된다는 것이다.
그리고 말했던 것처럼 개발자는 사람이기 때문에, 그런 실수를 저지를 수 있고, 이를 컴파일 단에서 막아주는 것이 좋다. 따라서 왠만하면 인자변수들을 final 로 해서 컴파일러가 재할당을 감지할 수 있도록 하면 좋을 듯 하다..
라고 할 수 있지만
왜 실제로 final parameter 가 달려있는 코드를 자주 못 보는 걸까?
이론상으로는 모든 인자에 final 을 달아주는게 좋겠지만, 실제로는 “메소드 코드의 길이가 너무 길거나, 복잡한 경우" 에만 위와 같은 사람의 오류가 생길거라고 가정하고 final 을 달아주는 게 좋을 것 같다.
'Java' 카테고리의 다른 글
타입 및 클래스들 사이에 존재하는 각 종 관계들과 리스코프 치환 원칙 (0) | 2023.03.24 |
---|---|
Java 에서 Stack 구현체로는 무엇을 사용해야할까?(feat_Java로 코딩테스트 문제 풀기) (0) | 2022.09.02 |
record 의 생성자를 private 으로 만드는 것이 불가능한 이슈 (0) | 2022.08.23 |
[Java] ImmutableCollection 과 UnmodifiableCollection 과 Immutability (0) | 2022.05.31 |
[Java] 주어진 배열에서 특정 값을 갖는 index 찾기 (stream) (참조글 읽어보기) (0) | 2022.03.08 |