서론
자바에서는 클래스의 속성이나 상태를 나타낼 때 주로 필드와 프로퍼티라는 두 가지 용어를 사용합니다.
코틀린에서는 클래스의 속성과 상태를 나타낼 때 프로퍼티라는 용어만 사용합니다.
그렇다면 Java에서의 필드와 프로퍼티, Kotlin에서의 프로퍼티는 어떤 차이가 있는 걸까요?
우선 자바의 필드와 프로퍼티를 살펴 보겠습니다.
Java의 field와 property
- field: 자신이 속한 클래스의 내부 변수. (속성 및 상태)
- property: 클래스의 내부 변수(필드)에 대해 접근자(getter/setter)를 사용해 접근하는 것.
필드와 접근자를 통틀어 가리키는 용어. - 필드는 외부에서 직접 접근이 가능합니다. 그러나 클래스 밖에서 직접 접근은 권장되지 않습니다.
즉, 접근자를 사용하는 프로퍼티 사용이 권장됩니다. - 따라서 자바에서는 필드를 private으로 설정하고, 접근자를 사용합니다.
위의 특징으로 인해 자바에서 필드만 사용하는 일이 거의 없어졌습니다.
자바에서는 관습적으로 getter와 setter를 작성하였습니다. 주로 프로퍼티만 사용하게 되었습니다.
때문에 코틀린에서는 이러한 보일러플레이트(반복되는 코드/접근자)를 줄이고자 하였습니다.
자바의 필드와 접근자를 코틀린에서는 프로퍼티 하나로 대체하였습니다.
필드를 없애고, 프로퍼티라는 용어만 사용할 수 있도록 진화하였습니다.
그럼 이제 Kotlin property의 특징에 대해 알아봅시다!
관련된 여러 특징은 자바로 역컴파일 하였을 때 이해가 쉽습니다.
때문에 모든 설명은 코드 예시와 함께 설명하겠습니다. :)
Kotlin의 property
자바에서의 필드처럼 보이는 코틀린의 프로퍼티
- 코틀린에서 byte코드로 변환될 때 필요에 따라 접근자가 자동으로 생성됩니다.
- 코틀린에는 자바의 필드처럼 보이는 접근자를 사용하는 프로퍼티만 존재합니다.
위의 코틀린 코드에서 변수 a는 분명히 자바의 필드처럼 보이지만,
역컴파일 하였을 때 접근자 게터가 있는 프로퍼티가 되어있는 것을 확인할 수 있습니다.
아래의 가변값에 대한 예시도 마찬가지입니다.
이 가변값에 대한 예시 또한
역컴파일 하였을 때 접근자 게터와 세터가 있는 프로퍼티가 되어있는 것을 확인할 수 있습니다.
방금 위에서 "필요에 따라 접근자가 자동으로 생성"이라는 문구가 있었는데요.
아래의 예시에서는 private 변수를 사용하고 있어 외부에 노출될 일이 없습니다.
따라서 접근자도 필요 없습니다.
접근자가 생성되지 않는 것을 확인할 수 있습니다.
사실 변수에 @JvmField 어노테이션을 사용한다면 public인 내부 변수 필드를 만들 수 있습니다.
외부에서 직접 접근할 수 있는 것이죠.
(하지만 이럴 거면 왜 코틀린을...? 왜 객체지향을...? 왜 굳이 클래스 분리를...? 하나 싶습니다...)
프로퍼티에 대해 기본 접근자 사용 불가
byte코드로 변환할 때 내부 변수에 대해 기본 접근자가 생성되기 때문입니다.
기본 접근자를 코틀린 코드에서 직접 작성해 보겠습니다.
아래와 같은 오류가 발생하는 것을 확인할 수 있습니다.
내부 변수에 대해 기본 접근자를 직접 정의할 수 없습니다.
byte 코드에서 동일한 식별자를 가진 메서드가 두 개가 생기기 때문입니다.
'접근자를 만들 수 없는 것인가?'라고 생각할 수 있지만, 기본 접근자만 만들 수 없는 것입니다.
메서드명을 getA()
와 같이 기본 접근자가 아닌 aValue()
와 같은 커스텀 접근자는 사용할 수 있습니다.
Backing fields
- 백킹 필드 (= 뒷받침하는 필드)
위의 예시를 보면 a의 접근자에서 field라는 이름을 가진 변수가 있습니다.
프로퍼티의 값을 저장하기 위한 필드입니다.
접근자 내부에서만 직접적으로 접근할 수 있습니다.
때문에 백킹 필드는 프로퍼티에 따라다니는 변수, 지원해 주는 변수 등으로 이해할 수 있겠습니다.
Computed property (계산된 프로퍼티)
- 내부 변수가 없는 property
- 필드로 뒷받침되지 않는 프로퍼티 (⇒ 필드가 없는 프로퍼티, getter만 있는 프로퍼티)
- 호출 시점에 따라 결과가 달라지는 프로퍼티에 적절하다. (내부 변수의 변경에 따른 계산값 변경 등)
결론 (다섯 줄 요약)
- 자바의 필드: 클래스 내부 변수
- 자바의 프로퍼티: 필드와 접근자
- 그러나 외부에서 필드에 직접 접근이 권장되지 않았다. 때문에 자바에서 습관적으로 프로퍼티만 사용하게 되었다.
따라서 코틀린에서는 반복되는 접근자를 생략하였다(개발자가 아닌 컴파일러에게 위임). 아래와 같은 개념이 된다. - "자바의 필드/프로퍼티 = 코틀린의 프로퍼티", "자바의 프로퍼티 ≠ 코틀린의 프로퍼티"
정리하며 생각한 것
코틀린은 간결하고 예쁜 언어이며 숨겨진 것들이 많은 코드인 것 같다.
간단하게 사용할 수 있도록 보이지 않는 곳에서 많이 가공되어 있다는 것을 느꼈다.
추가하고 싶지만 아직 정리가 덜 된 내용: 인스턴스 필드, 저장된 프로퍼티, 확장 프로퍼티
참고
- 수달의 프롤로그
- https://kotlinlang.org/docs/properties.html
- 『자바에서 코틀린으로』 (211p ~ 217p)
- 『Kotlin IN ACTION』 (71p ~ 74p)
코틀린 버전 1.8을 기준으로 작성하였습니다.
'kotlin > insight' 카테고리의 다른 글
Kotlin 에서의 원시값 포장과 그에 적합한 클래스 선택하기 (0) | 2023.04.08 |
---|---|
intellij에서 ktlint를 사용해 Kotlin 컨벤션 준수하기 (2) | 2023.02.07 |
댓글