본문 바로가기
Language/자바

왜 private인 필드가 변하지 않도록 하기 위해 final 키워드를 선언해야 하는가?(by.리플렉션)

by 띵커베르 2023. 2. 14.
728x90
  • 접근자 메서드가 없는 final 지시자로 선언한 클래스가 있고 모든 필드가 private 라면 클래스가 변하지 않는다고 생각하는 경향이 있다.
  • 하지만 그렇지 않다. 리플렉션 API 를 이용해서 필드가 보이는지와 상관없이 모든 필드에 접근하고 변경할 수 있다.
  • 또한 final 지시자는 해당 필드가 절대 수정되지 못하도록 JVM 에게 알려준다.
  • 덕분에 외부에서 접근할 수 없게 제대로 설정된 것처럼 보이지만 실제로는 외부에서 접근할 수 있는 방법이 몇 가지 있다.
  • 예를 들어 스프링의 IoC 컨테이너 같은 경우 @Autowired 어노테이션이 선언된 privatate 필드는 컨테이너가 실행 도중 초기화될 때 설정될 수 있다.
  • 아래코드는 리플렉션을 이용해 필드를 변경한 코드이다.
    @Test
    void mutateBookRecordState() throws IllegalAccessException, NoSuchFieldException {
        final BookRecord record = new BookRecord("jeong", "bestBook");
        Field author = record.getClass().getDeclaredField("author");
        author.setAccessible(true);
        author.set(record, "injin");

        assertThat("injin").isEqualTo(record.getAuthor());
    }

    public final class BookRecord {
        private String author;
        private String bookTitle;

        public BookRecord(String author, String bookTitle) {
            this.author = author;
            this.bookTitle = bookTitle;
        }

        public String getAuthor() {
            return author;
        }

        public String getBookTitle() {
            return bookTitle;
        }
    }
728x90

댓글