본문 바로가기

Kotlin/Basic

[Kotlin] 더블콜론(::) 참조

더블 콜론(::)


더블콜론(::)은 코틀린에서 메서드 참조, 프로퍼티 참조, 클래스 리터럴(Literal)과 같은 메타 프로그래밍에 관련된 것으로, 리플렉션을 위해 사용한다.

리플렉션이란 런타입에 프로그램의 클래스를 조사하기 위해서 사용되는 기술이다. 즉, 프로그램이 실행 중일 때 인스턴스 등을 통해 객체의 내부 구조 등을 파악할 수 있다.

코틀린에서 변수나 클래스명 앞에 더블콜론(::)을 명시하면, 변수나 클래스에 대한 참조를 할 수 있다. 더블콜론을 명시하면 변수가 아닌 객체(Object)로 접근할 수 있기 때문이다. (Object::class)

그럼 자바와 코틀린에서의 리플렉션 차이를 보자.

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

위는 자바에서 클래스를 참조할 때 사용하는 방식이다.

SomeClass::class
someInstance::class

위는 코틀린에서 클래스를 참조할 때 사용하는 방식이다.

안드로이드 프로그래밍 시, 우리는 액티비티를 넘길 때, MainActivity::class.java 와 같이 끝에 .java 를 붙이는 것을 볼 수 있다. 그 이유는 자바에서 쓰는 클래스와 코틀린에서 사용하는 클래스가 다르기 때문이다.

위 예시에서 자바의 SomeCalss.class는 class를 반환한다. 하지만, 코틀린에서는 SomeClass::class를 하면 KClass를 반환한다. 그렇기 때문에, KClass를 Class로 바꿔주어야 하는데, 이때 .java를 이용하여 자바 클래스 값을 받는 것이다.

KClass 안의 java의 getter는 아래 코드와 같이 확장함수 형태로 되어있으며, KClass에서 자바의 클래스 타입을 반환한다.

/**
* Retrun a Java[Class] instance corresponding to the given [KClass] instance.
*/ 
@Suppress("UPPER_BOUND_VIOLATED")
public val <T> KClass<T>.java: Class<T>
	@JvmName("getJavaClass")
	get() = (this as ClassBasedDeclarationContainer).jClass as Class<T>

함수 참조


위의 SomeClass:class와 같이 클래스를 참조할 수도 있지만, SomeClass::Method와 같이 클래스 내의 메소드도 참조할 수 있고, ::Function 형식의 함수도 참조 할 수 있다.

메서드를 참조하는 코드를 보자.

fun isOdd(x:Int): Boolean{
    return x % 2 !=0
}
fun isEven(x:Int): Boolean{
    return x%2 == 0
}
fun main(){
    val numList = listOf<Int>(1,2,3,4,5,6,7,8,9,10)
    println("Odd Num: ${numList.filter(::isOdd)}")
    println("Even Num: ${numList.filter(::isEven)}")
}
💬
<<결과>>

Odd Num: [1, 3, 5, 7, 9] Even Num: [2, 4, 6, 8, 10]

.filter를 사용해 함수 참조를 이용해 ::isOdd, ::isEven형태로 함수를 호출한다.

필터의 원형은 IntArray에서 Int값을 받아 Boolean을 반환하는 inline함수이다. 마찬가지로 Int를 받아 Boolean을 반환하기 때문에 함수를 참조하여 동일한 형식의 isOddisEven을 사용할 수 있다.


Uploaded by N2T