코틀린의 더블콜론(::) 참조
평소 더블콜론을 사용할때 자바의 클래스참조로 쓰이는 리플렉션과 같은 용도로 사용한다고만 이해하고 사용하는경우가 많았습니다.이번에 한번 더 정리를 하고자 작성하였습니다.
리플렉션(Reflection)이란
코틀린에서 더블콜론(::)은 리플렉션을 위해 사용합니다. 리플렉션이란 코드를 작성하는 시점에는 런타임상 컴파일된 바이트코드에서 내가 작성한 코드가 어디에 위치하는지 알 수 없기때문에 바이트코드를 이용해 내가 참조하려는 값을 찾기위해 사용합니다. 개인적으로 리플렉션이라는 단어가 반사,투영이라는 의미가 있기때문에 바이트코드를 통해서 투영된 코드를 참조한다는 뜻이 아닐까 싶습니다.
자바에와 코틀린에서의 리플렉션
SomeClass.class //클래스 그 자체를 리플렉션
someInstance.getClass() //인스턴스에서 클래스를 리플렉션
자바에서는 클래스를 참조할때 위와같이 사용합니다.
SomeClass::class
someInstance::class
코틀린에서는 더블콜론을 리플렉션을 위해 사용하며 위와같은 형태로 사용합니다. 하지만 우리가 액티비티를 넘길때는 SomeClass::class.java와 같이 끝에 .java가 붙는것을 볼 수 있습니다. 그 이유는 자바에서 쓰는 클래스와 코틀린에서 쓰는 클래스가 다르기 떄문입니다. 자바에서의 ‘SomeClass.class’는 Class를 리턴하고 반면 코틀린에서는 SomeClass::Class를하면 KClass를 리턴합니다. 그렇기때문에 KClass를 Class로 바꾸어주어야하는데 이때 ‘.Java’를 이용하여 자바클래스 값을 받습니다.
KClass 안의 java의 getter는 위 그림과 같이 확장함수 형태로 되어있으며 KClass에서 자바의 클래스 타입을 반환합니다.
코틀린에서의 함수참조
코틀린에서 SomeClass::class와 같이 클래스를 참조할수도 있지만 SomeClass:Method와같이 클래스 내의 메서드도 참조할 수 있고 ::Function형식의 함수도 참조할 수 있습니다.
fun isOdd(x:Int):Boolean{
return x % 2 != 0
}
//단축형
//fun isOdd(x: Int) = x % 2 != 0
홀수를 체크하는 함수는 위 코드와같이 표현할 수 있고 람다식으로 표현한다면 정수를 받아 불을 리턴하는 (Int) -> Boolean 와 같이 표현할 수 있습니다. 만약 isOdd를 Filter를 이용해 사용한다면 아래 그림과 같이 사용할 수 있습니다.
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
//출력 [1,3]
혹시 이해가 가지 않는다면 필터의 원형을보면 쉽습니다.
inline fun IntArray.filter(
predicate:(Int) -> Boolean
)
필터의 원형은 IntArray에서 Int값을받아 Boolean을 리턴하는 인라인함수입니다. 마찬가지로 Int를 받아 Boolean을 리턴하기때문에 함수를 참조하여 동일한 형식인 isOdd를 사용할 수 있습니다.