제네릭(Generic)은 클래스 내부에서 사용할 자료형을 나중에 인스턴스를 생성할 때 확정된다
자료형의 객체들을 다루는 메서드나 클래스에서 컴파일 시간에 자료형을 검사해 적당한 자료형을 선택할 수 있도록 하기 위해서 제네릭이 등장
open class Parent
class Child: Parent()
class Cup<T>
fun main() {
val obj1:Parent = Child()
//val obj2:Child = Parent() // 에러 child 객체 obj2 는 parent 로 변환 불가
//val obj3: Cup<Parent> = Cup<Child>() // 에러
//val obj4:Cup<Child> = Cup<Parent>() // 에러
val obj5 = Cup<Child>();
val obj6: Cup<Child> = obj5
}
fun <형식 매개변수[...]> 함수명(매개변수: <매개변수 자료형>[, ...]): <반환 자료형>
fun <T> genericFunc(arg: T): T? { ... } // 매개변수와 반환 자료형에 형식 매개변수 T가 사용됨
fun <K, V> put(key: K, value: V): Unit { ... } // 형식 매개변수가 여러 개인 경우
class Box<in T: Animal>(var item: T)
class Box<T>(var item: T)
...
fun <T> printObj(box: Box<out Animal>) {
val obj: Animal = box.item // item의 값을 얻음(get)
box.item = Animal() // 오류
println(obj)
}
fun <T> myGenericFun(c: Class<T>)
inline fun <reified T> myGenericFun()
package part2.chap04.section1
fun main() {
val result = getType<Float>(10)
println("result = $result")
val result2 = getType<Int>(1)
println("result2 = $result2")
val result3 = getType<Double>(2)
println("result3 = $result3")
}
inline fun <reified T> getType(value: Int) :T {
println(T::class) // 실행 시간에 삭제되지 않고 사용 가능
println(T::class.java)
return when (T::class) { // 받아 들인 제네릭 자료형에 따라 반환
Float::class -> value.toFloat() as T
Int::class -> value.toInt() as T
else -> throw IllegalStateException("${T::class} is not supported")
}
}
[결과 화면]
class kotlin.Float
class java.lang.Float
result = 10.0
class kotlin.Int
class java.lang.Integer
result2 = 1
class kotlin.Double
class java.lang.Double
Exception in thread "main" java.lang.IllegalStateException: class kotlin.Double is not supported
at part2.chap04.section1.ReifiedGenericKt.main(ReifiedGeneric.kt:42)
at part2.chap04.section1.ReifiedGenericKt.main(ReifiedGeneric.kt)
Process finished with exit code 1