
최근 채용공고에서 토스 뿐만 아니라 여러 서비스 기업들이 코틀린을 많이 요구하는 게 눈에 띈다. 자바에서 코틀린으로 넘어오는 이유와 어떤 게 차별점인지 알아보고, 기초 내용에 대해 정리하고자 한다.
자바에서 코틀린으로 넘어온 이유를 널 안정성, 가독성, 그 외 기본 문법 세 가지로 나누어 본다.
코틀린 연습 및 정리 Git
https://github.com/1000bang/kotlin_webflux_study.git
GitHub - 1000bang/kotlin_webflux_study: kotlin_webflux_study
kotlin_webflux_study. Contribute to 1000bang/kotlin_webflux_study development by creating an account on GitHub.
github.com
1. 널 안정성
자바에서는 String 만 봐서는 null이 들어갈 수 있는지 알 수 없고, 실수는 런타임에 NullPointerException으로 드러난다. 코틀린은 null 가능 여부를 타입에 포함시켜 컴파일 단계에서 막을 수 있다.
1-1. 컴파일 에러
nullable 타입은 타입? ex) var name : String?
non-null 타입은 타입 그대로 쓴다. non-null에 null을 넣으면 컴파일 시점에 에러가 난다.
var name: String = "토스"
name = null // 컴파일 에러: Null can not be a value of a non-null type String
var nickname: String? = "토스페이"
nickname = null // OK
1-2. Safe call (?.)
nullable 변수에 '.' 으로 바로 접근하면 컴파일 에러가 나므로, safe call로 “null이면 이 줄 실행 안 함”을 표현한다.
val nickname: String? = null
val length = nickname?.length // nickname이 null이면 length도 null. NPE 없음.
// 자바였다면: nickname != null ? nickname.length() : null
1-3. Elvis 연산자 (?:)
“null이면 오른쪽 값 쓰기”를 한 줄로 쓸 때 사용한다.
val nickname: String? = null
val displayName = nickname ?: "이름 없음" // "이름 없음"
val len = nickname?.length ?: 0 // null이면 0
// java
String displayName = nickname != null ? nickname : "이름 없음"
2. 가독성
보일러플레이트가 줄고, 의도가 코드에 잘 드러나도록 문법이 설계되어 있다.
2-1. 타입 추론
초기화 값으로 타입을 알 수 있으면 타입을 생략할 수 있다. 정적 타입은 그대로라서, 나중에 다른 타입을 대입하면 컴파일 에러가 난다.
val name = "토스" // String
val count = 42 // Int
val list = listOf(1, 2, 3) // List<Int>
2-2. 싱글톤 object
싱글톤이 필요할 때 클래스 대신 object 하나로 인스턴스 하나를 보장한다.
object Config {
const val API_URL = "https://api.toss.im"
fun getTimeout() = 30
}
// 사용
Config.API_URL
Config.getTimeout()
2-3. data class
getter/setter, equals, hashCode, toString을 자동 생성해 주는 data class로 DTO를 짧게 쓴다.
data class UserDto(
val id: Long,
val name: String,
val email: String? = null,
)
val user = UserDto(1L, "토스", "toss@example.com")
println(user) // UserDto(id=1, name=토스, email=toss@example.com)
2-4. Named argument
인자에 이름을 붙여서 가독성을 높이고, 기본값과 함께 쓰면 필요한 것만 넘길 수 있다.
data class UserDto(
val id: Long,
val name: String,
val email: String? = null,
val nickname: String? = null,
)
// 순서 상관없이, 필요한 것만
UserDto(id = 1L, name = "토스")
UserDto(name = "토스", id = 1L, nickname = "토스페이")
2-5. Collection function
컬렉션을 Stream 없이 filter, map 등을 바로 쓸 수 있다.
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 } // [2, 4, 6, 8, 10]
val evens = numbers.filter { it % 2 == 0 } // [2, 4]
val sum = numbers.sum() // 15
3. 그 외 기본 문법
3-1. var / val
- val: 읽기 전용 (재할당 불가)
- var: 재할당 가능
val immutable = "바꿀 수 없음"
var mutable = "바꿀 수 있음"
mutable = "변경"
3-2. 문자열 템플릿
$변수 또는 ${식} 으로 문자열 안에 값을 넣는다.
val name = "토스"
println("회사 이름: $name")
println("길이: ${name.length}")
// java 에서는
System.out.println("회사이름 : " + name);
3-3. when (switch 대신)
여러 분기를 간단히 쓸 수 있고, 식처럼 사용하면 값을 반환할 수 있다.
val message = when (data) {
1 -> "일"
2 -> "이"
in 4..10 -> "four to ten"
is String -> "string"
else -> "other"
}
3-4. 기본값 인자
함수 파라미터에 기본값을 두면 호출 시 생략할 수 있다.
fun greet(name: String, prefix: String = "안녕하세요") = "$prefix, $name"
greet("토스") // "안녕하세요, 토스"
greet("토스", "반갑습니다") // "반갑습니다, 토스"
//자바에서는
String greet (String name, String prefix) {
return prefix + name;
}
String greet (String name) {
Stirng prefix = "반갑습니다"
return prefix + name;
}
4. 정리
자바에서 코틀린으로 넘어오는 이유를 널 안정성, 가독성, 그 외 기본 문법으로 나누어 정리했다.
- 널 안정성: 타입에 ?를 넣어 컴파일 단계에서 null 오류를 줄이고, safe call, elvis로 null 처리를 짧게 쓸 수 있다.
- 가독성: 타입 추론, object, data class, named argument, collection function으로 코드 양이 줄고 의도가 잘 드러난다.
- 기본 문법: val/var, 문자열 템플릿, when, 기본값 인자 등은 자바에 비해 더 짧고 읽기 쉽게 쓸 수 있다.
추가로 Kotlin DSL, Kotlin JDSL, 테스트 관련 글을 참고하면 좋다.
https://toss.tech/article/kotlin-dsl-restdocs
Kotlin으로 DSL 만들기: 반복적이고 지루한 REST Docs 벗어나기
토스페이먼츠에서는 API docs를 REST Docs를 사용해서 작성할 수 있도록 권장하고 있습니다. 이 글에서는 DSL을 통해서 반복적인 REST Docs 테스트 코드 작성을 줄일 수 있는 방법을 알아봅니다.
toss.tech
https://www.youtube.com/watch?v=9O9YjopIiEQ
'Language' 카테고리의 다른 글
| [Python] 크롬브라우저 제어하기 : Selenium, ChromeDriver, Jupyter Notebook, Mac (16) | 2024.11.06 |
|---|---|
| [markdown] 마크다운 기본 사용방법 (0) | 2024.10.05 |
| [C] function (0) | 2024.10.02 |
| [C] 포인터 (6) | 2024.10.02 |