코틀린 시작하기 — 자바 개발자를 위한 첫걸음
자바를 쓰다가 코틀린을 처음 접하면 "이게 같은 JVM 위에서 돌아간다고?" 싶을 정도로 문법이 간결하다. 세미콜론도 없고, getter/setter도 없고, null 처리까지 언어 차원에서 해준다. 면접에서 "코틀린 써봤냐"는 질문이 늘고 있어서, 자바 개발자 관점에서 코틀린의 첫 단추를 정리해봤다.
val과 var — 변수 선언의 기본
코틀린에서 변수를 선언하는 방법은 딱 두 가지다.
- val — 재할당 불가 (자바의
final과 비슷) - var — 재할당 가능
val name = "코틀린" // 재할당 불가
var count = 0 // 재할당 가능
// name = "자바" // 컴파일 에러!
count = 1 // OK
면접에서 자주 나오는 포인트
"val은 불변인가요?" 라는 질문에 바로 "네"라고 답하면 감점이다. val은 재할당이 불가능할 뿐, 객체 내부의 상태는 변할 수 있다.
val list = mutableListOf(1, 2, 3)
list.add(4) // OK — 리스트 내부 상태 변경
// list = mutableListOf() // 컴파일 에러 — 재할당 불가
자바의 final 변수와 정확히 같은 개념이라고 설명하면 면접관이 좋아한다.
타입 추론 — 타입을 안 써도 되는 이유
코틀린은 컴파일러가 초기화 값을 보고 타입을 알아서 결정한다. 이걸 **타입 추론(Type Inference)**이라고 한다.
val message = "Hello" // String으로 추론
val number = 42 // Int로 추론
val pi = 3.14 // Double로 추론
명시적으로 타입을 적어도 된다.
val message: String = "Hello"
val number: Int = 42
타입 추론이 안 되는 경우
초기화 없이 선언만 하면 타입을 반드시 명시해야 한다.
val name: String // 나중에 초기화할 예정
// val name // 컴파일 에러 — 타입을 알 수 없음
공부하다 보니 여기서 많이 헷갈렸는데, 코틀린은 정적 타이핑 언어다. 타입을 안 쓴다고 동적 타이핑이 아니라, 컴파일 타임에 타입이 확정된다.
Nullable 타입 — 물음표 하나의 차이
코틀린에서 가장 중요한 특징 중 하나다. 기본적으로 모든 타입은 null을 허용하지 않는다.
var name: String = "코틀린"
// name = null // 컴파일 에러!
var nullableName: String? = "코틀린"
nullableName = null // OK
타입 뒤에 ?를 붙이면 Nullable 타입이 된다. 이 간단한 규칙 하나로 NPE(NullPointerException)를 컴파일 타임에 잡아낸다.
fun getLength(text: String?): Int {
// return text.length // 컴파일 에러 — null일 수 있음
return text?.length ?: 0 // 안전 호출 + 엘비스 연산자
}
Nullable에 대한 더 자세한 내용은 별도 글에서 다루겠다.
String Template — 문자열 조합의 혁명
자바에서 문자열을 조합하려면 + 연산이나 String.format()을 썼는데, 코틀린은 $ 하나로 해결된다.
val name = "코틀린"
val version = 2.0
// 변수 직접 삽입
println("언어: $name") // 언어: 코틀린
// 표현식 삽입
println("버전: ${version + 0.1}") // 버전: 2.1
// 여러 줄 문자열
val json = """
{
"name": "$name",
"version": $version
}
""".trimIndent()
자바와 비교
// 자바
String result = "이름: " + name + ", 버전: " + version;
String result2 = String.format("이름: %s, 버전: %.1f", name, version);
// 코틀린
val result = "이름: $name, 버전: $version"
면접에서 이 포인트를 물어보더라고요 — "가독성과 생산성" 측면에서 답하면 된다.
when 표현식 — switch의 완전한 상위 호환
자바의 switch는 제약이 많았는데, 코틀린의 when은 훨씬 강력하다.
기본 사용법
val grade = 'A'
val result = when (grade) {
'A' -> "우수"
'B' -> "보통"
'C' -> "미흡"
else -> "알 수 없음"
}
when의 강력한 기능들
// 여러 값 매칭
when (x) {
0, 1 -> println("0 또는 1")
else -> println("기타")
}
// 범위 검사
when (score) {
in 90..100 -> "A"
in 80..89 -> "B"
in 70..79 -> "C"
else -> "F"
}
// 타입 검사
when (obj) {
is String -> println("문자열 길이: ${obj.length}") // 스마트 캐스트
is Int -> println("정수 값: $obj")
else -> println("알 수 없는 타입")
}
// 인자 없는 when (if-else 대체)
when {
temperature > 30 -> println("더움")
temperature > 20 -> println("적당")
else -> println("추움")
}
자바 switch와의 차이점
| 특징 | Java switch | Kotlin when |
|---|---|---|
| Fall-through | 있음 (break 필요) | 없음 |
| 표현식 사용 | Java 14부터 | 처음부터 |
| 타입 검사 | Java 17부터 | 처음부터 |
| 범위 검사 | 불가 | in 연산자 |
| 인자 없는 형태 | 불가 | 가능 |
자바와의 100% 호환
코틀린의 가장 큰 장점 중 하나는 자바와 완벽하게 호환된다는 점이다. 같은 JVM 위에서 돌아가기 때문에 가능한 일이다.
코틀린에서 자바 코드 호출
// 자바 라이브러리를 그대로 사용
import java.util.ArrayList
import java.time.LocalDateTime
val list = ArrayList<String>()
list.add("코틀린에서 자바 컬렉션 사용")
val now = LocalDateTime.now()
자바에서 코틀린 코드 호출
// 코틀린 파일: Utils.kt
fun greet(name: String): String {
return "안녕, $name!"
}
// 자바에서 호출
String result = UtilsKt.greet("자바");
코틀린 최상위 함수는 파일명Kt 클래스의 정적 메서드로 컴파일된다. @JvmStatic, @JvmOverloads 같은 어노테이션으로 자바 호출을 더 자연스럽게 만들 수 있다.
점진적 마이그레이션이 가능하다
기존 자바 프로젝트
├── src/main/java/ ← 기존 자바 코드 유지
│ └── UserService.java
├── src/main/kotlin/ ← 새 코드는 코틀린으로
│ └── OrderService.kt
면접에서 "자바 프로젝트를 코틀린으로 전환한 경험이 있냐"는 질문이 나오면, 이 점진적 마이그레이션 전략을 설명하면 된다. 한 번에 전부 바꾸는 게 아니라, 새로운 코드부터 코틀린으로 작성하고 기존 자바 코드와 공존시키는 방식이다.
자바 개발자가 주의할 점
코틀린으로 넘어올 때 자주 실수하는 부분을 정리했다.
1. 세미콜론이 없다
val name = "코틀린" // 세미콜론 불필요
2. new 키워드가 없다
val list = ArrayList<String>() // new 없이 생성
val user = User("심정훈", 28) // new 없이 생성
3. 기본 가시성이 public이다
class User(val name: String) // public이 기본
// 자바는 package-private가 기본
4. checked exception이 없다
// 코틀린은 checked exception을 강제하지 않음
fun readFile(path: String): String {
return File(path).readText() // throws 선언 불필요
}
정리
코틀린은 자바의 장점을 유지하면서 단점을 개선한 언어다. 면접에서 핵심을 정리하면 이렇다.
- val/var: val은 재할당 불가(≠ 불변), var는 재할당 가능
- 타입 추론: 컴파일 타임에 타입이 결정되는 정적 타이핑
- Nullable:
?하나로 NPE를 컴파일 타임에 방지 - String Template:
$와${}로 문자열 조합 - when: fall-through 없는 강력한 패턴 매칭
- 자바 호환: 같은 프로젝트에서 자바와 코틀린 공존 가능
자바를 이미 알고 있다면, 코틀린은 "더 적게 쓰고 더 안전한 코드"를 만드는 도구라고 생각하면 된다. 자바와 100% 호환되니까 부담 없이 시작해보자.