안드로이드 스튜디오 - 코틀린과 자바 차이(2)

Jang Seok Woo·2021년 7월 20일
0

실무

목록 보기
65/136

늦은 초기화 lateinit

말 그대로 초기화를 늦게 시킨다는 말이다.

프로퍼티를 null 허용으로 선언하지 않고 프로퍼티 초기화를 미루는 방법, 이 방법은 lateinit 예약어를 이용하며, '늦은 초기화'라고 부릅니다.

아래의 예시코드를 보면 이해에 도움이 됩니다.

01 package eight_two_three

02

03 class User1 {

04   lateinit var lateData: String

05 }

06

07 fun main(args: Array<String>) {

08   // lateinit

09   val user = User1()

10   user.lateData = "hello"

11   println(user.lateData)

12 }

위의 코드를 보면 04번 줄에서 프로퍼티를 선언하면서 초깃값을 설정하지 않았으며 대신 lateinit을 명시했습니다. 그다음 10번 줄에서 프로퍼티 값을 초기화해서 사용했습니다. 이처럼 늦은 초기화를 이용하면 프로퍼티의 선언과 동시에 초기화하지 않아도 됩니다.

그런데 늦은 초기화는 사용 시 주의할 점이 많습니다. 다음과 같은 제약이 있습니다.

lateinit는 var로 선언한 프로퍼티에만 사용할 수 있다.
lateinit는 클래스 몸체, Top-Level, 함수 내부에 선언한 프로퍼티에 사용할 수 있다. 주 생성자에서는 사용할 수 없다.
lateinit는 사용자 정의 getter/setter를 사용하지 않은 프로퍼티에만 사용할 수 있다.
null 허용 프로퍼티에는 사용할 수 없다.
기초 타입 프로퍼티에는 사용할 수 없다.

01 lateinit var data1: String //성공

02

03 class User2(lateinit var data: String) { //에러

04   lateinit val data2: String //에러

05   lateinit var data3: String? //에러

06   lateinit var data4: Int //에러

07   lateinit var data5: String //성공

08 }

03번 줄은 주 생성자에 추가해서 에러입니다.
04번 줄은 val로 선언한 프로퍼티에 lateinit를 추가해서 에러입니다.
05번 줄은 var로 선언했지만, null 허용으로 선언한 프로퍼티에 lateinit를 추가해서 에러입니다.
06번 줄은 기초 타입인 Int로 선언한 프로퍼티에 lateinit를 추가해서 에러가 발생합니다.

더블콜론(::)

코틀린에서 더블콜론(::)은 리플렉션을 위해 사용한다. 리플렉션이란 코드를 작성하는 시점에는 런타임상 컴파일된 바이트 코드에서 내가 작성한 코드가 어디에 위치하는지 알 수 없기 때문에 바이트 코드를 이용해 내가 참조하려는 값을 찾기위해 사용한다.

SomeClass.class -> 클래스 그 자체를 리플렉션
someInstance.getClass() -> 인스턴스에서 클래스를 리플렉션

자바에서는 클래스를 참조할 때 위와 같이 사용한다.

SomeClass::class
someInstance::class

코틀린에서는 더블콜론을 리플렉션을 위해 사용하며 위와 같은 형태로 사용한다.

하지만 우리가 액티비티를 넘길 때는 SomeClass::class.java와 같이 끝에 .java가 붙는 것을 볼 수 있다. 그 이유는 자바에서 쓰는 클래스와 코틀린에서 쓰는 클래스가 다르기 때문이다.

자바에서의 SomeClass.class는 Class를 리턴한다. 반면, 코틀린에서는 SomeClass::class를 하면 KClass를 리턴한다. 그렇기 때문에 KClass를 Class로 바꾸어 주어야하는데 이때 .Java를 이용하여 자바 클래스 값을 받는다.

뷰 참조

코틀린에서는 뷰의 id를 그냥 쓰면 바로 참조한다.

이게 진짜 놀라운 일이다..

무슨말이냐면,

    TextView mTextureView;
    mTextureView = findViewbyId(R.id.texture);
    mTextureView.setText("Hello World!");

이렇게 해야했던 부분이

    texture.setText("Hello World!")

이렇게 하면 그냥 된다는 말이다.

profile
https://github.com/jsw4215

0개의 댓글