[kotlin] Generic 맛만 보기

우발자·2026년 3월 28일

안드로이드 개발을 하면서 Generic를 써봤지만 제대로 이해하고 쓴 적이 없는 것 같다.
그래서 이번 기회에 무슨 맛인지만 볼려고 한다.


🥸 제네릭(Generic)이란?

제네릭이란 간단하게 말하자면 타입을 일반화해서 재사용성을 높이는 문법이다.
특히 타입 안정성과 유연성이 좋기 때문에 많이 사용된다.

😓 그래서 어떻게 사용하는건데..?


제네릭은 총 5가지에 타입이 있다.

기본 형태는

class Box<T>(val value : T)

이런식으로 사용한다.

😇 그래서 장점이 뭔데...

간단한 예시를 들자면

내가 Log를 남기기 위해 Log 남기는 함수를 만든다고 생각해보자.
근데 파라미터의 값이 Int도 있고 String도 있다고 가정해보자.
그럼 타입별로 함수를 만들어야된다.

// Int형
fun printInt(value : Int) { 
	println(value
}

// String형
fun printInt(value : String) { 
	println(value
}

하지만 제네릭을 쓰면

fun <T>print(value : T) {
	println(value)
}

하나로 해결이 가능하다.

하지만 별도에 타입별로 처리를 안해줘도 되는 이유는

println의 파라미터 타입이 Any?이기 때문이다.

/** Prints the given [message] and the line separator to the standard output stream. */
public actual fun println(message: Any?) {
    printlnImpl(message?.toString())
}

그렇기 때문에 타입 캐스팅을 안해줘도 되는 것이다.

만약 파라미터 타입이 정해져있으면 타입 캐스팅을 별도 처리 해줘야된다.

👮🏼 타입 제한 (Upper Bound)

제네릭을 사용할 때 타입을 제한할 수도 있다. 예를 들면

fun <T : Number> sun(a : T, b : T) : Double {
	return a.toDouble() + b.toDouble()
}

Number의 하위 타입만 받을 수 있다는 뜻이다. 그래서
Number을 상속받는 Int, Long, Float, Double만 받을 수 있고 나머지 타입은 모두 컴파일 에러가 뜬다.

공변성과 반공변성에 대해서도 알고 싶으면 부족하지만 나의 이전글을 확인해도 좋다


🥳 그래서 실무에서 어떻게 사용될까?

지금 현재 회사에서는 Composable한 함수를 재사용되기 위해 많이 사용되는데

보통 앱을 만들 때 각 회사마다 디자인 시스템이 있다. 지금 만들고 있는 앱도 디자인 시스템이 있다. 그래서 공통적으로 쓰는 컴포넌트가 있는데 대표적으로 Tabs에 대해 소개해보고 싶다.

앱 개발자라면 Tabs를 많이 사용해봤을 것이다.

요런 느낌인데 이런 컴포넌트들이 앱내에 공통적으로 사용된다.
근데 각 화면에 같은 디자인들을 매번 코드를 작성하기엔 비효율적이다.
그래서 보통 이런 디자인시스템에서 공통 컴포넌트들은 재사용 가능하게끔 만든다.

☝️ 우선 Interface로 보여줄 값들을 정의한다.

interface Tabs {
	val title : String // Tab 화면에 보여질 텍스트
}

Tabs에선 보통 title하나면 충분하기 때문에 하나만 정의했다.

𝟚 제너릭 공통 함수 생성

@Composable
fun <T : Tabs> TabBar(
	tabs: List<T>,
	selectedTab : T,
	onSelectedTab : (T) -> Unit
) {
 ...
}

제네릭 타입을 T를 받되 타입 제한을 지정하여 Tabs를 상속받은 구현체만 받도록 했다.

3️⃣ 구현하여 사용해보자.

 // Tabs 구현
enum class MainTabs(override val title : String) : Tabs {
 	HOME("홈"),
 	MY("마이"),
 	SEARCH("검색")
 }
 

// MainScreen.kt
 TabBar(
 	tabs = MainTabs.entries,	
	selectedTab = MainTabs.HOME,
 	onSelectedTab = viewModel::onSelectedTab
 )

이렇게 하면 Tabs를 각 화면에 맞게 생성만 해준다면 번거롭게 매번 로직을 생성 안해도 재사용 할 수 있게된다.
그게 바로 제너릭에 장점인 것 같다.


👨🏼‍💻 후기

제너릭은 개발을 하면서 꼭 필요한 문법인 것 같다. 화면을 만들때도 최대한 재사용을 할려고 노력한다. 앞으로 제너릭을 더 활용하는 개발자가 되고싶다.

profile
어제보다 나은 개발자가 되자

0개의 댓글