본문 바로가기
  • 개발하는 곰돌이
Programming Language/Kotlin & Java

[Java/Kotlin] 필드(Field)와 프로퍼티(Property)는 무슨 차이가 있을까?

by 개발하는 곰돌이 2023. 5. 2.

목차

    들어가기 전에

    처음 코틀린에 대해 공부하기 시작하면서 프로퍼티에 대한 내용을 다룰 때 좀 혼란스러운 느낌이 있었다. 자바 클래스의 필드를 이야기하는 것 같다가도 조금 다른듯한 느낌이었기 때문이다. 그래서 당시에는 그냥 어차피 비슷한 개념이고, 언어마다 명칭이 다른가보다 하면서 코틀린 클래스의 프로퍼티 = 자바 클래스의 필드의 느낌으로 인식하고 사용했다.

     

    그러다가 최근에 객체지향의 사실과 오해(조용호 저)에 대한 스터디를 진행하면서 프로퍼티라는 단어가 나와서 이야기를 조금 했었는데, 비슷한 개념인 것은 맞지만 다른 점이 있다는 이야기를 들어서 확실하게 정리해야겠다는 생각이 들었다.

    필드(Field)와 프로퍼티(Property)

    결론부터 말하자면 프로퍼티는 객체가 갖는 상태와 같은 속성이고, 필드는 프로퍼티의 실제 값이라는 차이가 있다. 객체지향의 사실과 오해에서는 이를 프로퍼티 값(Property Value)라고 칭한다.

    @Getter
    @Setter
    public class Member {
        private String name;
        private int age;
        private String phoneNumber;
    }

    위의 Member 클래스의 예로 들면 name, age, phoneNumber는 프로퍼티가 되고, 이들의 실제 값은 필드가 된다고 볼 수 있다.

     

    가장 큰 차이로는 프로퍼티는 정적인 반면에 필드는 동적이라는 점이다. 예를 들어, 위 Member에서 name, age, phoneNumber는 각각 회원의 이름, 나이, 전화번호라는 속성이 된다. name이 거주지 주소가 되거나 age가 몸무게가 되는 등의 변경을 할 수 없는 것이다.

     

    하지만 필드는 변경될 수 있다. 회원의 이름이 "라이언"이었다가 이후 개명하여 "춘식이"로 변경될 수 있다. 이 때 프로퍼티인 name이 이름이라는 것은 변하지 않지만 이 값은 "라이언"에서 "춘식이"로 바뀌게 된다.

     

    여기서 필드와 프로퍼티의 차이를 알 수 있는데, private 변수인 name, age, phoneNumber 각각의 프로퍼티를 담는 필드가 된다. 그리고 이들의 Getter는 해당 프로퍼티의 필드 값을 조회하는 메소드가 되고, Setter는 해당 프로퍼티의 필드 값을 변경하는 메소드가 된다고 볼 수 있을 것이다. 정확한 것은 아니지만 아래의 그림과 같이 필드가 프로퍼티에 포함되는 구조라고 볼 수 있지 않을까 싶다.

    코틀린과 자바에서의 용어 차이

    그런데 코틀린에서는 클래스의 멤버 변수를 프로퍼티라고 칭하고, 자바에서는 필드라고 칭한다. 이는 두 언어의 차이를 생각해봐야 할 것 같다.

     

    자바에서는 기본적으로 클래스의 멤버 변수를 선언할 때 private으로 선언하게 되고 Getter와 Setter는 Lombok을 사용하거나 직접 작성해야 한다. 이렇게 선언된 멤버 변수는 Getter와 Setter가 존재하지 않고 객체를 생성할 때 값만 저장된다. 또한 멤버 변수를 다룰 때도 직접적으로 다루지 않고 String name = member.getName();이나 member.setName("춘식이");처럼 Getter와 Setter를 사용해서 간접적으로 다루게 된다. 이렇게 자바 클래스의 멤버 변수는 값만 갖고있기 때문에 필드라고 칭하는 것이다.

     

    반면에 코틀린에서 클래스의 멤버 변수를 선언하게 되면 자바 바이트코드 상으로는 자동으로 Getter와 Setter가 함께 생성된다. 이렇게 자동으로 생성된 Getter와 Setter는 자바처럼 val name = member.getName()이나 member.setName("춘식이")의 형태로도 사용할 수는 있지만 기본적으로는 val name = member.name이나 member.name = "춘식이"와 같이 멤버 변수를 직접 다루는 형태로 사용하게 된다.(실제로 직접 다루는 것은 아니지만)

    코틀린 클래스는 멤버 변수만 선언한 클래스라도 자바 코드로 디컴파일 해보면 자동으로 Getter와 Setter가 생성되어 있다.

    다만 코틀린의 경우에는 실제 멤버 변수가 존재하지 않더라도 커스텀 Getter를 통해 프로퍼티를 정의할 수 있다. 아래와 같은 Rectangle 클래스에서 area는 변수처럼 선언되었지만 실제로 존재하는 변수가 아니다.

    class Rectangle(var height: Int, var width: Int) {
        val area get() = height * width
    }

    이 클래스를 자바 코드로 디컴파일 해보면 area라는 멤버 변수가 존재하는 것이 아니라, getArea()라는 메소드만 존재하는 것을 확인할 수 있다.

    하지만 코틀린에서는 이 area를 사용할 때 단순히 rectangle.area와 같이 멤버 변수를 참조하는 형태로 사용할 수 있다. 

    이렇듯, 코틀린 클래스의 프로퍼티는 엄밀히 말하면 단순 멤버 변수만을 지칭하는 것이 아니라 더욱 광범위한 개념을 지칭한다고 볼 수 있을 것이다.

    마치며

    필드와 프로퍼티는 둘 모두 멤버 변수에 근간을 둔다는 점에서 비슷하긴 하지만 둘은 엄연히 다른 개념인 것 같다. 프로퍼티는 개념적인 느낌이라면 필드는 좀 더 물리적인 느낌이라고 할 수 있는 느낌?

     

    그 외에도 자바는 필드라는 용어를 사용하고 코틀린은 프로퍼티라는 용어를 사용하는 등의 언어별로 사용하는 용어의 차이는 해당 언어의 특징에 맞게 알맞은 용어를 선택한 것이라는 느낌도 들었다.

     

    개념적인 느낌이 강한 구분이라 말로 정리하기가 어려워서 제대로 표현한 것이 맞는지는 애매하지만 그래도 확실한 차이가 있다는 점은 알 수 있었다.

    댓글