본문 바로가기
kotlin/insight

Kotlin에서의 프로퍼티, Java에서의 필드와 프로퍼티

by 코드 이야기 2023. 4. 10.
728x90

 

서론

자바에서는 클래스의 속성이나 상태를 나타낼 때 주로 필드프로퍼티라는 두 가지 용어를 사용합니다.

코틀린에서는 클래스의 속성과 상태를 나타낼 때 프로퍼티라는 용어만 사용합니다.

그렇다면 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만 있는 프로퍼티)
    • 호출 시점에 따라 결과가 달라지는 프로퍼티에 적절하다. (내부 변수의 변경에 따른 계산값 변경 등)

 

 

 

결론 (다섯 줄 요약)

  • 자바의 필드: 클래스 내부 변수
  • 자바의 프로퍼티: 필드와 접근자
  • 그러나 외부에서 필드에 직접 접근이 권장되지 않았다. 때문에 자바에서 습관적으로 프로퍼티만 사용하게 되었다.
    따라서 코틀린에서는 반복되는 접근자를 생략하였다(개발자가 아닌 컴파일러에게 위임). 아래와 같은 개념이 된다.
  • "자바의 필드/프로퍼티 = 코틀린의 프로퍼티", "자바의 프로퍼티 코틀린의 프로퍼티"

 

 

 

 


정리하며 생각한 것

코틀린은 간결하고 예쁜 언어이며 숨겨진 것들이 많은 코드인 것 같다.
간단하게 사용할 수 있도록 보이지 않는 곳에서 많이 가공되어 있다는 것을 느꼈다.
추가하고 싶지만 아직 정리가 덜 된 내용: 인스턴스 필드, 저장된 프로퍼티, 확장 프로퍼티


참고

코틀린 버전 1.8을 기준으로 작성하였습니다.

 

728x90

댓글