본문 바로가기

안드로이드 프로그래밍/kotlin

[KotlinSyntax] Properties and Fields

프로퍼티 선언


코틀린 클래스는 프로퍼티를 가질 수 있음

var (mutable) / val (read-only)

class Address {
	var name: String = "kotlin"
    val city: String = "Busan"
}

 

 

프로퍼티 사용은 자바의 필드를 사용하듯이 하면 됨

fun copyAddress(address: Address): Address {
	val result = Address()
    result.name = address.name
    //..
    return result
}

 

 

 

 

 

 

 

프로퍼티 문법


전체 문법

var <propertyName>[: <PropertyType>] [=<property_initializer>]
[<getter>]
[<setter>]

옵션 (생략 가능)

  • PropertyType
  • property_initializer 에서 타입을 추론 가능한 경우 생략 가능
  • property_initializer
  • getter
  • setter

 

val (read-only) 프로퍼티

var 대신 val 키워드 사용

setter가 없음

 

 

 

 

 

 

Custom accessors (getter, setter)


custom accessor 는 프로퍼티 선언 내부에, 일반 함수 처럼 선언 할 수 있음

 

getter

val inEmpty: Boolean
	get() = this.size == 0

setter

  • 관습적으로 setter 의 파라미터의 이름은 value 임 (변경가능)
var stringRepresentation: String
	get() = this.toString()
    set(value) {
    	setDataFromString(value)
    }

 

 

타입 생략

코틀린 1.1 부터는 getter 를 통해 타입을 추론할 수 잇는 경우, 프로퍼티의 타입을 생략할 수 있음

val inEmpty: Boolean
	get() = this.size == 0 // has type Boolean
    
    
val inEmpty
	get() = this.size == 0 // has type Boolean

 

 

 

 

 

 

프로퍼티


accessor 에 가시성 변경이 필요하거나

accessor에 어노테이션이 필요한 경우

기본 accessor의 수정 없이 body 없는 accessor를 통해 정의 가능

var setterVisibility: String = "abc"
	private set
var setterWithAnnotation: Any? = null
	@inject set // annotate the setter with inject

Body를 작성해 주어도 됨

var setterVisibility: String = "abc"
	private set(value) {
    	field = value
    }

 

 

 

 

 

Backing Fields


코틀린 클래스는 field를 가질 수 없음

'field' 라는 식별자를 통해 접근할 수 있는, automatic backing field를 제공함

field는 프로퍼티의 accessor에서만 사용가능 함

// the initializer value is written directly
// to the backing field
var counter = 0
	set(value) {
    	if(value >= 0) field = value
    }

 

Backing Fields 생성 조건

accessor 중 1개라도 기본 구현을 사용하는 경우

custom accessor에서 field 식별자를 참조하는 경우

 

 

implicit backing field 방식이 맞지 않은 경우에는 backing propery 를 이용할 수 도 있음

 

 

 

 

 

 

 

 

Compile-Time Constants


const modifier를 이용하면 컴파일 타임 상수를 만들 수 있음

  • 이런 프로퍼티는 어노테이션에서도 사용가능함

 

조건

  • Top-level 이거나
  • object 의 멤버이거나
  • String 이나 프리미티브 타입으로 초기화된 경우

 

 

 

Late-Initialized Properties


일반적으로 프로퍼티는 non-null 타입으로 선언됨

간혹 non-null 타입 프로퍼티를 사용하고 싶지만, 생성자에서 초기화를 해줄 수 없는 경우가 있음

  • Dependency injection
  • Butter knife
  • Unit test 의 setiup 메소드
public class MyTest {
	lateinit var subject: TestSubject
    
    @Setup fun setup() {
    	subject = TestSubject()
    }
    
    @Test fun test() {
    	subject.method() 
    }
}

 

객체가 constructor 에서는 할당되지 못하지만 여전히 non-null 타입으로 사용하고 싶은 경우 

Lateinit modifier 를 사용 가능

조건

  • 클래스의 바디에서 선언된 프로퍼티만 가능
  • 기본생성자에서 선언된 프로퍼티는 안됨
  • var 프로퍼티만 가능
  • custom accessor 이 없어야 함
  • non-null  타입이어야 함
  • 프리미티브 타입이면 안됨

lateinit 프로퍼티가 초기화 되기 전에 접근되면, 오류가 발생됨

  • kotlin.UninitializedPropertyAccessException: lateinit property tet has not been initialized
728x90
반응형