특정 코드를 여러 타입에 대해 재사용 하고 싶을 때, 정확히 어떤 타입이 들어오게 될 지 미리 알 수 없을 때 제네릭 타입을 사용한다. 코틀린에서 모든 타입을 받기 위해 사용하는 Any, *가 어떻게 다른건지 글로 정리해두려 한다.

 

Any class

Any는 코틀린에서 모든 타입이 상속받는 최상위 타입이다. 자바로 디컴파일 해보면 Object 타입으로 변환되며, 내부엔 equals(), hashCode(), toString()같은 메서드가 정의되어 있다. 제네릭 타입으로 Any를 사용하면 어떤 객체를 집어넣든 업캐스팅이 적용돼서 모든 타입이 들어갈 수 있게 된다.

 

예제를 보면 arrayList가 Int, String, Float 모든 타입을 원소로 받을 수 있다.

fun main() {
    val arrayList = arrayListOf<Any>()
    arrayList.add("안녕")
    arrayList.add(1)
    arrayList.add(3.14)

    println(arrayList.joinToString()) // 출력 결과 : 안녕, 1, 3.14
}
fun acceptAnyList(list: ArrayList<Any>) {
    list.add("문자열") // work
    list.add(1)      // work
}

 

참고 : Any와 Object의 차이점

  • 자바에서는 참조 타입만 Object를 최상위 클래스로 상속받는다, 코틀린은 원시타입과 참조타입을 구별하지 않기 때문에 Any가 모든 타입의 조상 클래스가 된다.
  • wait(), notify(), notifyAll()처럼 쓰레드를 제어하는 메서드는 Any에 없다. 사용하려면 (any as Object).notify() 이런 식으로 형변환이 필요하다.

 

* (Star-projections)

*는 어떤 타입이 들어올지 미리 알 수 없어도 그 타입을 안전하게 사용하고 싶을 때 사용한다. 언제든지 모든 타입을 받을 수 있는 Any와 달리 한번 구체적인 타입이 정해지고 나면 해당 타입만 받을 수 있다.

 

이런식으로 작성하면 arrayList의 타입이 영원히 결정되지 못하므로 syntax error가 발생한다.

val arrayList = arrayListOf<*>() // error!

ArrayList가 어떤 타입으로 초기화될지 알 수 없으므로 String, Int 타입을 추가하려 하면 syntax error가 발생한다.

fun acceptStarList(list: ArrayList<*>) {
    list.add("문자열") // error!
    list.add(1)      // error!
}

*는 구체적인 타입이 정해지기 전까지는 Any?로 취급된다.

fun acceptStarList(list: List<*>) {
    if (list.isNotEmpty()) {
        val item = list.get(0) // IDE가 item을 Any? 타입으로 추정
    }
}

이런 식으로 SuperClass 또는 SuperClass의 자식 클래스만 들어올 수 있게 범위가 지정된 제네릭 클래스가 있다고 가정해보자.

open class SuperClass
class Child : SuperClass()

open class TestClass

class GenericClass<out T : SuperClass>() { }

여전히 T 자리에 어떤 타입이 들어올지 모르는 시점에서 GenericClass를 인자로 받는 메서드를 선언하기 위해 * 키워드를 사용했다. 그러면 acceptStart()를 호출할 때 지정해둔 범위에 맞지 않는 타입이 들어갔을 경우 syntax error가 발생한다.

fun acceptStar(value: GenericClass<*>) {}

fun main() {
    acceptStar(GenericClass<Child>())
    acceptStar(GenericClass<SuperClass>())
    acceptStar(GenericClass<TestClass>()) // error!
}

 

 

참고 자료