Final

ymk·2023년 6월 12일
0
post-thumbnail

📢 Final이란?

final은 마지막의, 또는 변경될 수 없는의 의미를 가지고 있으며 거의 모든 대상에 사용될 수 있다. 변수에 사용되면 변경할 수 없는 상수가 되고, 메서드에 사용되면 오버라이딩을 할 수 없게 된다. 클래스에 사용되면 자신을 확장하는 자손 클래스를 정의하지 못하게 된다.

변수 final
final을 사용하여 변수를 초기화하는 방법은 두가지가 있다.

  • 먼저 단순히 한 값을 초기화 하려면 클래스 필드에 상수의 형태로 사용한다.
public static final String CONSTANT_PARAGRAPH = "HELLO";

상수는 보통 public static final로 선언한다. Static을 통해 컴파일때 메모리 할당을 한번만 하기 때문에 효율적이다.

  • 두번째로는 final이 사용된 변수를 생성자에서 초기화하는 것이다.
Class main() {
	private final int number;
    
   main(int number) {
   	this.number = number;
   }
}

이 경우는 변수에 값을 할당하기 전에 별도의 로직이 실행되어야 하는 등 복잡할 때 사용한다.

변수에 사용될때 정확히는 해당 변수는 더이상 '재할당' 할 수 없게 된다. 그래서 final을 사용한다고 값이 불변한다고 말할 수는 없다. Final은 변수의 재할당을 막지, 참조하고 있는 객체의 내부의 상태까지 변하지 않도록 보장하지는 않는다.

final List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3));
numbers.add(4) // 가능

⚡ Effectively final?

Java 8에서 추가된 syntactic sugar 일종이다. (syntactic sugar = 문법적 기능은 그대로인데 그것을 읽는 사람이 직관적으로 쉽게 코드를 읽을 수 있게 만든다는 것)
초기화 된 이후에 값이 단 한번도 변하지 않았으면 effectively final 이라고 할 수 있다. Effectively final은 final 키워드를 붙이지 않았지만 컴파일러는 이런 변수를 final을 붙인 것과 동일하게 처리한다.

이러한 effectively final은 anonymous class나 람다식에서 코드를 좀 더 간결하게 만들어 준다. Java 7에서 익명클래스는 외부 지역 변수가 final인 경우에만 접근이 가능했기 때문에 항상 final 키워드를 추가해줘야 했다. 하지만 Java 8에서의 effectively final을 통해서도 접근이 가능하게 바뀌어 조건만 만족하면 final 키워드를 생략할 수 있다.

// Java 7
public void testPlus() {
        final int number = 1;

        Addable addableImple = new Addable() {
            @Override
            public int plusOne() {
                return number + 1;
            }
        };
}

// Java 8
public void testPlus() {
        int number = 1; // Effectively final

        Addable addableImple = new Addable() {
            @Override
            public int plusOne() {
                return number + 1;
            }
        };
}

Reference

Java의 정석 - 3rd Edition by. 남궁 성
https://hudi.blog/java-final/
https://vagabond95.me/posts/lambda-with-final/

profile
개발 공부 일지

0개의 댓글