1. 코틀린의 이해
2. 기본 문법
- 변수 선언
- 함수 선언
1. 코틀린의 이해
핀테크/결제 기업들이 백엔드에 코틀린을 도입하는 이유를 알고 싶어 조사해봤다.
1원만 틀려도 대형 사고가 터지는 결제/핀테크 백엔드 시스템에서 자바의 불편함과 반복 코드를 줄이고 안정성을 강화하기 때문이라고 한다.
1-1. 코틀린을 쓰는 4가지 이유
결제 백엔드는 대용량 트래픽 처리, 돈과 관련된 데이터 무결성, 빠른 기능 배포가 생명이다. 코틀린은 이 세 가지를 모두 만족한다.
- JVM 상호 운용과 점진적 전화 (Gradual Adoption)
- 대형 핀테크/결제 시스템은 오랫동안 Java와 Spring Framework로 구축된 경우가 많다.
- Kotlin은 같은 JVM 바이트코드를 대상으로 하며, Java와 상호 운용이 잘 되도록 설계되어 있어, 기존 Java 코드베이스를 한 번에 교체하지 않고 신규 API, 모듈만 Kotlin으로 추가하는 식의 단계적 전환이 가능하다.
- 다만 Kotlin은 Java의 문법적 상위 집합이 아니며 null 안정성, 기본 인자, 확장 함수 등은 Java에서 그대로 쓰이지 않을 수 있다. 따라서 100% 동일 호환이나 전환 리스크 제로가 아니라 레거시 Java와 Kotlin을 한 프로젝트 함 팀에서 병행 운영하는 전략에 적합하다고 보는 것이 정확하다.
- Spring Boot는 Kotlin을 공식 지원하며, 공식 문서와 튜토리얼에서도 Kotlin 예제를 지속적으로 제공하고 있다.
- Spring Boot Kotlin 지원: Spring Boot가 Kotlin을 어떻게 공식 지원하는지, null safety, coroutines, extension function, data class 지원 등과 연동
- Spring 공식 튜토리얼 (Spring Boot + Kotlin): 실제로 Kotlin 기반 Spring Boot 프로젝트를 만드는 공식 가이드
- Kotlin 공식: JetBrains(Kotlin 제작사)에서 제공하는 Spring Boot 입문 문서 Spring Boot는 Kotlin을 공식 지원하며, 공식 문서와 튜토리얼에서도 Kotlin 예제를 지속적으로 제공하고 있다.
- 널 안정성 (Null Safety)로 NPE 리스크 감소
- 자바에서 흔한 런타임 오류 중 하나가 NullPointerException(NPE)이다. 결제나 정산 경로에서 이 에러가 나면 요청이 실패하거나 재시도 처리에 따라 상태 불일치로 이어질 수 있어 운영 리스크가 크다.
- Kotlin은 타입 시스템에서 nullable(String?)과 non-nullable(String)을 구분한다. null을 안전하게 처리하지 않으면 컴파일 단계에서 오류가 나는 경우가 많아, NPE를 설계, 빌드 단계에서 상당 부분 예방할 수 있다.
- 다만, 알아두어야 할 건 NPE를 완전히 없애는 것은 아니다. Java 라이브러리 연동(platform type), !! 사용, 잘못된 가정 등으로 런타임 NPE는 여전히 가능하다. 또한 중복 결제, 누락 방지는 null 안전성만으로 충분하지 않고, 멱등 키, 트랜잭션, 재시도 정책 등 별도 설계가 필요하다.
- Kotlin에서 NPE가 나는 경우
- Java API 연동 시 platform type(String! 등) : 컴파일러가 null 여부를 모른다.
- !!, 잘못된 lateinit 사용
- Map.get() 등으로 null이 들어오는 경우를 non-null로 가정
- Kotlin에서 NPE가 나는 경우
- DTO *보일러플레이트 감소와 가독성 (Data Class & 불변성)
- 결제 시스템은 주문서, 결제 요청, 영수증, 정산 내역 등 데이터 객체(DTO)가 많다.
- 레거시 스타일이 강한 Java에서는 getter/setter, equals/hashcode 등으로 코드가 길어지기 쉽다. Kotlin의 data class는 동등성, 해시, toString, copy 등을 자동 생성해 선언을 짧게 유지할 수 있다. 코드가 읽기 쉬워지면 리뷰와 변경 추적에 유리하다.
- 불변성은 data class만으로 보장되지 않는다. 필드를 val로 두고 필요시 copy()로 변경하는 패턴이 결제 도메인에서 안전한 편이다. Java 16이상의 record도 DTO 보일러플레이트를 줄이는 대안이 있다. ( 레거시 Java 8 환경이면 Kotlin/data class 비교는 여전히 유효함)
*보일러플레이트 : 최소한의 수정만으로 여러 곳에서 재사용되며, 반복적으로 작성해야 하는 필수 코드 블록을 의미함
- 비동기/동시 처리 표현 (코루틴, Coroutines)
- 이벤트, 정산 등 동시 요청이 몰리는 구간에서는 스레드만 늘리는 방식보다 I/O 대기를 효율적으로 다루는 구조가 중요하다.
- Kotlin의 코루틴(Coroutines)은 운영체제 스레드보다 가벼운 단위로 동시 작업을 표현하기 좋고, 콜백 지옥 없이 비동기 코드를 순차 코드처럼 작성할 수 있다. I/O가 많은 워크로드에서 적은 스레드로 많은 동시 작업을 다루는 데 유리할 수 있다.
- 다만 코루틴만 도입한다고 결제 트래픽이 자동으로 해결되지는 않는다. 논블로킹 I/O, DB, HTTP 클라이언트, Spring WebFlux 등과 맞는 아키텍처가 함께 가야 한다. 블로킹 JDBC, 전통 MVC만 쓰는 서비스에서는 효과가 제한적일 수 있다. 대규모 처리는 코루틴과 더불에 메시지 큐, 파티셔닝, DB 튜닝, 수평 확장이 핵심인 경우가 많다.
- I/O 대기가 많은 워크로드에서 스레드 수를 줄이면서 동시성을 표현하기에 적합하다. Java 21 이상에서 가상스레드도 비슷한 축의 경량 동시성을 제공한다.
1-2. Kotlin의 쓰임새
Kotlin은 구글이 안드로이드 공식 언어로 채택하면서 널리 알려졌다. 이후 JVM 기반 백엔드, Kotlin Multiplatfor(KMP) 등으로 영역이 넓어져, 특정 플랫폼에만 쓰이는 언어가 아니라 범용 언어에 가깝게 성장했다.
[코틀린의 생태계]
┌─────────────────────────────────────────────────────────────────┐
│ 코틀린(Kotlin)의 생태계 │
└───────────────────────────────────┬─────────────────────────────┘
│
┌─────────────────────────────┼───────────────────────────┐
▼ ▼ ▼
[ 백엔드 서버 ] [ 안드로이드 앱 ] [ 멀티플랫폼 (KMP) ]
Spring Boot 기반 구글 공식 지정 언어 공통 로직, 네트워크, 데이터 계층 공유
REST API/MSA/핀테크,이커머스 등 신규 주요 앱에서 (UI는 플랫폼 별 또는 Compose Multiplatform 등)
Kotlin 비중 높음
- 웹 백엔드 서버(Spring Boot): 국내에서 카카오, 네이버, 토스, 우아한형제들 등 대규모 서비스에서 Kotlin과 Spring 조합이 흔하다. 채용 공고에 Kotlin 경험 우대가 자주 보이며 신규, 신규 모듈에서 채택이 늘고 있다.
- 안드로이드: 안드로이드 스튜디오에서 권장 언어이며, 신규 안드로이드 프로젝트는 Kotlin이 주류에 가깝다.
- Kotlin 멀티플랫폼(KMP): 도메인 로직, API 클라이언트, 직렬화 등 플랙폼 공통 코드를 iOS, Android, 데스크톱, 웹 등에서 공유한다. 화면(UI)까지 100%까지 한 벌이 아닌 경우가 많아 공유 범위를 명확하게 하는 것이 중요하다.
1-3. 코틀린의 전체적인 핵심 특징 요약
아래는 코틀린이라는 언어의 전체 정체성을 이해하기 위한 4대 키워드라고 한다.
- 정적 타입 지정 언어: 컴파일 시 타입을 검사해 실행 전 오류를 많이 잡는다. 자바와 유사하며, Kotlin은 여기에 nullable 타입으로 null 관련 오류를 더 줄인다.
- 객체 지향 + 함수 프로그래밍: 클래스 기반 객체 지향과, 함수를 값으로 다루는 함수형 스타일을 함께 쓸 수 있는 다패러다임 언어다.
- 실용주의 언어: 문법, 표준 라이브러리가 개발 생산성(보일러플레이트 감소, 읽기 쉬운 코드)을 중시한다.
- 도구 지원: 제작사 JetBrains(IntelliJ)의 언어로, IntelliJ IDEA / Android Studio에서 자동완성·리팩토링·탐색 지원이 매우 강하다
2. 기본 문법
2-1. 변수 선언: val과 var
Kotlin에서 변수는 val(참조 재할당 금지)과 var(가변) 두 가지로 나뉜다.
기본적으로 val을 쓰고, 값이 바뀌어야 할 때만 var를 쓰는 게 원칙이다.
참고로 val은 변수 자체의 재할당을 막지만 참조하는 객체 내부 상태까지 완전히 불변이라는 뜻은 아니다.
val name = "Kotlin" // 재할당 불가
var count = 0 // 재할당 가능
count = 1
//타입을 명시할 수도 있다.
val userId: Long = 1001L
var isLoggedIn: Boolean = false
// 참조하는 객체 내부 상태까지는 완전히 불변이 아니다.
val numbers = mutableListOf(1,2,3)
numbers.add(4) // 가능
📌실무에서는 val을 최대한 쓰는 게 좋다.
값이 어디서 바뀌는 지 추적할 필요가 없어서 코드를 읽기 쉬워진다.
2-2. 함수 선언
함수는 fun 키워드로 선언한다. 반환 타입은 : 뒤에 명시한다.
// 기본 함수
fun add(a: Int, b: Int): Int {
return a + b
}
// 단일 표현식 함수 (간결하게)
fun add(a: Int, b: Int): Int = a + b
// 반환값이 없으면 Unit (생략 가능)
fun printHello(): Unit {
println("Hello, Kotlin!")
}
// 기본값 파라미터
fun greet(name: String, greeting: String = "안녕") {
println("$greeting, $name!")
}
greet("철수") // 안녕, 철수!
greet("영희", "반가워") // 반가워, 영희!
// 이름 있는 인수(Named Arguments)
greet(name = "민수", greeting = "좋은 아침")
📌 실무에서는 기본값 파라미터와 이름 있는 인수는 메서드 오버로딩을 줄여주는 데 유용하다.
'Language > Kotlin' 카테고리의 다른 글
| [복습] 1~3강까지 미션 (0) | 2026.05.27 |
|---|---|
| [Kotlin] Coroutine 기초 (0) | 2026.05.20 |
| [Kotlin] Collection API & 함수형 프로그래밍 (0) | 2026.05.20 |
| [Kotlin] Scope Function 완전 정리 (0) | 2026.05.20 |
| [Kotlin] Kotlin 핵심 문법 3가지 (0) | 2026.05.20 |