java final 세팅과 사용법
java에서 final로 불변 값/변수를 사용
📜 제목으로 보기
final 키워드로 값의 변경을 막아라
final 세팅 in IDE, 지역 변수, 메소드 파라미터
- 지역변수, 파라미터 모두 final로 생성되도록 하자
- 설정 > Editor > Code style > java > Code generation >
Make ~ final
체크박스 2개
- 설정 > Editor > Code style > java > Code generation >
-
main 메소드 template 인
psvm
의 인자에도final
을 붙혀준다.- 설정 > live template or psvm 검색 > final 붙여주기
final 값 -> 재할당을 막아 불변
- 메서드 내부에서 코드 중간에서 가변 변수를 수정할 때, 위에 재할당 등의 수정이 되었었나 확인해야한다.
-
final
로 재할당(재사용)이 불가능한불변 값
사용하다가,변수의 재사용
이 필요할 경우 새 변수를 만들어서 쓰자.
-
-
모든 지역변수, 인자에 final을 붙이자.
-
final로 값을 초기화(선언후 할당)하는 방법은 2가지다
//1. final변수 선언과 동시에 && 할당 -> final은 재할당 불가 -> 변수재사용시 새객체 반환할 것 final int i = 2; i = 4; // java: cannot assign a value to final variable i //2. final변수 먼저 선언 -> 이후 할당 // 생성자 등에서 값을 외부에서 받아와 추가 로직(convert or default 대입 등 특수 case(if) 존재)이후 초기화 final int number; number = 5;
final 객체 -> 메서드로 내부 변화 가능 -> 메서드를 항상 새 객체로 응답
-
객체의 경우는
final
로는 완벽한 불변을 못만든다.- final 값와 달리
final 객체
는 메소드 등에 의해내부가 변할 수 있다.(포인터의 포인터에서 껍데기 포인터1)
- final 값와 달리
-
객체를 불변으로 만든 법
상태변화를 일으키는 기능들은 새로운 객체를 반환
하도록 정의하자.-
상태변화 시켰던 메서드의 void returnType에
해당 객체를 응답(return)
하도록 수정// 내부변화되는 final 객체 public void move() { this.position++; } // 1. 일단 응답을 동일 객체로 만들어주기 public Car move() { this.position++; }
-
변화된 상태
로 new생성자()로 호출하여 -> 새로운 객체를 반환시킨다.//2. 응답 객체를, 변화된 값으로 새로 만들어서 응답 -> 내부 값은 변화 없다. public Car move() { return new Car(this.position + 1); } //3. 생성자를 통해 응답할 객체를 만들어준다. 내부 값의 변화는 없게 한다. public Car(final int position) { this.position = position; }
-
final 메서드, 클래스 -> 자식이 못 쓰게
package domain;
final public class FinalParent {
final void finalMethod() {
final String asdfasdf = "asdfasdf";
}
}
package domain;
//2. final 클래스는 자식이 상속이 안된다.
// java: cannot inherit from final domain.FinalParent
public class FinalChild extends FinalParent {
//1. final 메소드는 자식이 오버라이딩 못된다. -> 코어 부분에서 변경을 원치 않는 메소드를 명시할 때 사용
//java: cannot find symbol, symbol: class FinalParent
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}
final 컬렉션(내부 변경api를 제공하는 껍데기포인터1) 등은 응답시 copy(unmodifiable) 해서 응답하라
- my)
포인터1의 포인터2
에 의해 변경될 수 있으니, 껍데기 포인터1 자체를 copy해서 응답해라 - 컬렉션을 반환할 때, 메모리주소가 공유되니, 어디서든 같은 컬렉션이 변경되는 위험이 있다.
- copy해서 전혀 다른 메모리의 컬렉션으로 응답하자.
List<String> names = List.of(); // unmodifiableList
names.add("텍스트") // 예외발생
- 내가 만든 일급컬렉션이라면 불변(내부 변화 기능 제공 않함)이 되겠지만, **일반 컬렉션이라면, 반환시 메모리주소가 공유된다. -> `unmodifiableList`로 copy된 메모리를 반환시켜 테스트 등 변화가 발생하게 하자.**
컨밴션 중 하나가 된다.
-
final
을 붙이는 것은 컨벤션이며 팀 안에서는 따르는게 좋을 수 도 있다.- 내 생각에 타당하지 않으면 얘기를 꺼내서 바꿀 수 있다.
- 컨벤션이라면, 비효율적이라도 그대로 가는 경우가 많다.
- 디자인 패턴 역시, 효율적이거나 좋은 코드라서 뿐만 아니라
커뮤니케이션을 줄이는 컨밴션
이기 때문에 좋기도 하다.
- 디자인 패턴 역시, 효율적이거나 좋은 코드라서 뿐만 아니라