Page 21 -
P. 21
9.1.1 제네릭 선언
어떤 선언을 제네릭 선언으로 만들려면 하나 이상의 타입 파라미터를 추가해야 한다. 이렇게 추가
한 타입 파라미터를 선언 내부에서는 일반적인 타입 대신 사용할 수 있다. 선언을 사용할 때는(예
를 들어 클래스 인스턴스를 만들거나 함수를 호출할 때는) 타입 파라미터를 대신할 실제 타입을
지정해야 한다.
val map = HashMap<Int, String>()
val list = arrayListOf<String>()
컴파일러가 문맥에서 타입 인자의 타입을 추론할 수 있으면 타입 인자를 생략할 수 있는 경우도
있다. 9
// map의 타입을 명시했기 때문에 HashMap 클래스의 타입 인자를 추론할 수 있음 제네릭스
val map: Map<Int, String> = HashMap()
// arrayListOf()에 전달된 인자의 타입(모두 String)으로부터 타입 인자를 추론할 수 있음
val list = arrayListOf("abc", "def")
자바 vs. 코틀린 코틀린과 자바의 제네릭 메서드에 타입 인자를 전달하는 방식의 차이에 유의하라.
자바에서는 Collections.<String>emptyList()처럼 점 바로 뒤에 각괄호를 사용해 타입을 전달하
지만, 코틀린에서는 emptyList처럼 함수 이름 바로 뒤에 타입을 전달한다. 다만 자바에서는 new
ArrayList() 같은 스타일을 사용하고 코틀린에서는 ArrayList() 같은 방식을 사용하기 때문에 클
래스 생성자를 호출하는 방법은 비슷하다.
자바도 클래스 생성자를 호출할 때 타입 추론을 지원하지만, 코틀린과 달리 다이아몬드 연산자
(<>)를 추가해야 한다.
Map<Int, String> map = new HashMap<>() // new HashMap()이 아님!!!
이유는 제네릭스가 추가된 자바 5 이전 코드와의 하위 호환성을 유지하기 위해서다.
이제 직접 제네릭 선언을 만들어보자.
어떤 주어진 타입의 값을 저장할 수 있는 트리를 표현하는 클래스를 정의하고 싶다고 하자.
class TreeNode<T>(val data: T) {
private val _children = arrayListOf<TreeNode<T>>()
var parent: TreeNode<T>? = null
361
Kotlin_05.indd 361 2022-02-15 오후 4:08:04