제네릭은 클래스 내부에서 사용할 자료형을 나중에 생성할 때 결정하도록 도와줍니다.
제네릭을 사용함으로서 자료형의 안정성이 높아지고, 형 변환의 번거로움이 줄어듭니다.
또한, 이후 컬랙션의 사용에도 큰 도움이 됩니다.
자바와 비슷하게 코틀린에서도 제네릭을 사용합니다.
<>사이에 매개변수를 넣는 방식으로 동일하게 사용합니다.
간단한 예시로 한번 살펴보겠습니다.
class Box<T>(arg:T){
var name = arg
}
fun main() {
val box1:Box<Int> = Box<Int>(1)
val box2:Box<String> = Box<String>("box")
println("${box1.name} ${box2.name}")
}
/*
Output
1 box
*/
위와 같이 타입을 T로 지정해주고, 이후에 T에 원하는 자료형을 붙여서 사용할 수 있습니다.
이 때, T는 foo bar 같은 많이 쓰이는 이름일 뿐 강제되지 않습니다.
또한 main에서 변수 선언 시 Box<Int>와 같이 타입지정을 해주지 않아도 알아서 추론해서 캐스팅해줍니다.
제네릭 함수 / 메서드
타입을 매개변수로 받는 함수 / 메서드를 제네릭 함수 / 메서드라고 부릅니다.
fun <타입 매개변수, ...> 함수 이름(매개변수 : <매개변수 자료형>):<반환 자료형>
위와 같은 방식으로 사용할 수 있으며, 타입 매개변수를 여러 개를 사용하기도 합니다.
fun<T> find(a: Array<T>, Target: T):Int{
for(i in a.indices){
if(a[i] == Target) return i;
}
return -1
}
fun main() {
var arr1: Array<String> = arrayOf("apple","bananan","cherry","grape")
var arr2:Array<Int> = arrayOf(1,2,3,4)
println("범위는 ${arr1.indices}")
println("범위는 ${arr2.indices}")
println(find<String>(arr1, "cherry"))
println(find(arr2,2))
}
위의 코드와 같이 사용할 수 있으며, 마지막의 find(arr2,2)와 같이 <>타입 선언을 빼도 정상 작동한다.
제네릭 함수에서의 연산은 자료형을 결정할 수 없기 때문에 오류가 발생한다. 이런 오류를 해결하기 위하여 람다식을 매개변수로 받아서 연산을 진행한다.
fun<T> add(a:T, b:T, op:(T,T)->T):T{
return op(a,b)
}
fun main() {
val res = add(2,3,{a,b -> a+b})
println(res)
}
제네릭에서 +연산을 진행할 때, +연산에 정의된 자료형이 없기에 오류가 발생하나, 람다식을 이용하여 자료형과 함께 넘겨주는 방식을 이용하면 해결 할 수 있습니다.
또한 위의 코드는 가독성을 올리기 위하여 아래와 같이 변경할 수 있습니다.
typealias arith<T> = (T,T)->T
fun<T> add(a:T, b:T, op:arith<T>):T{
return op(a,b)
}
fun main() {
val res = add(2,3,{a,b -> a+b})
println(res)
}
이외에 람다식을 따로 정의하여 가독성을 높여줄 수 있습니다.
자료형 제한
타입 매개변수 '<T>' 에 자료형을 제한할 수 있습니다.
<T:Number>와 같이 특정한 자료형을 붙여서 제한하는 방법이 있습니다.
위에서 사용한 코드를 이용하여 예시를 보겠습니다.
typealias arith<T> = (T,T)->T
fun<T:Number> add(a:T, b:T, op:arith<T>):T{
return op(a,b)
}
fun main() {
val res = add(2,3,{a,b -> a+b})
println(res)
val res1 = add("23","34",{a,b -> a+b})
println(res1)
}
아래에 res1을 만들고 String타입을 연산하는 함수를 만들어줬습니다.
여기서 <T>였다면 정상작동을 하지만, <T:Number>로 Number형으로 제한하여 String 타입의 연산인 res1은 오류가 발생합니다.
'Java & Kolin' 카테고리의 다른 글
Sentry에서 Cron 모니터링이 가능하다는 사실 (1) | 2024.10.14 |
---|---|
M1 사용기 - JVM환경에서 ARM / Rosetta 번역 알아내기 (0) | 2021.10.10 |
Garbage Collection (0) | 2021.04.04 |
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (0) | 2021.03.30 |
Spring 오류 / The signing key's size is 240 bits which is not secure enough for the HS256 algorithm. (0) | 2021.02.12 |
댓글