지난 글에서는 코틀린의 등장배경에 대해 알아봤다. 이번엔 코틀린에 대한 특성 및 자바와의 비교, 그리고 직접 써보면서 느꼈던 점들을 코드와 함께 풀어보려 한다.


코틀린의 주요 특성

코틀린, 어디에 쓰는 언어일까?

코틀린은 처음부터 자바 대신 쓸 수 있는 언어를 목표로 만들어졌다.
그래서 자바가 돌아가는 환경이면 대부분 잘 작동한다:

  • 백엔드 서버 개발 (Spring, Ktor 등)
  • 안드로이드 앱
  • JS 타겟 (브라우저나 Node.js)
  • 필요하다면 네이티브 개발도 가능(Kotlin/Native)

정적 타입지정 언어

그리고 코틀린은 정적 타입 언어다.
타입을 명시적으로 쓰지 않아도 컴파일러가 알아서 추론하고 검증한다.

val name = "JazzyByte" // 자동으로 String으로 인식

덕분에 타입 안정성을 챙기면서도, 코드는 간결하게 쓸 수 있다.


코틀린이 자바보다 좋은 이유

1. 코드가 정말 확 줄어든다

처음엔 진짜 놀랐다. DTO 하나 만들자고 getter, setter, toString, equals, hashCode… 자바에선 모두 써야 했다. 코틀린에선?

data class User(val id: Long, val name: String)

끝이다.

확인해보면 Lombok 같은 보조 도구 없이도, 기본적인 기능들이 다 들어있다.

fun main() {
    val user = User(1L, "JazzyByte")
 
    // 1. 객체 출력(toString() 구현 없이 된다.)
    println(user) 
    // 출력 결과: User(id=1, name=JazzyByte)
 
    // 2. 프로퍼티 접근
    println("생성된 유저의 이름은 ${user.name}입니다.")
}

2. 널 안정성(NPE)에서 해방

자바 개발자라면 한 번쯤은 겪어봤을 NullPointerException.
코틀린은 아예 언어 차원에서 null을 다르게 취급한다.

val name: String? = null println(name?.length ?: 0)

nullable인지 아닌지를 타입 자체에 명시하고,
컴파일 타임에 실수를 막아준다.


3. 읽기 쉬운 문법

코틀린은 전반적으로 눈이 편한 언어다.

Java:

public final String greet(String name) { 
	return "Hello, " + name; 
}

Kotlin:

fun greet(name: String) = "Hello, $name"

when, val, extension function, top-level function, lambda
자바보다 구조도 단순하고, 문법도 훨씬 직관적이다.


4. 컬렉션 처리

val result = names.filter { it.length > 3 }
				.map { it.uppercase() }

한 줄만 봐도 무슨 로직인지 감이 온다.
자바의 stream().filter().map().collect()보다 훨씬 간결하고 읽기 쉬워졌다.


알아두면 좋은 것들

코틀린은 내부적으로 어떻게 돌아갈까?

코틀린은 JVM 기반 언어다. 자바처럼 .class 바이트코드로 컴파일돼서 JVM 위에서 실행된다. (컴파일러는 전용 kotlinc를 )

// Hello.kt 
fun main() {     
	println("Hello, Kotlin!") 
}

이 코드를 컴파일하면 HelloKt.class가 만들어지고, 자바처럼 실행할 수 있다. JVM의 생태계를 그대로 누리면서도, 더 현대적인 문법을 사용 한다.

Kotlin Runtime Library란?

Kotlin에는 자체 표준 라이브러리가 있다.
여기엔 자주 쓰는 확장 함수들 (let, run, apply, map, filter 등)이 포함돼 있어서,
자바보다 훨씬 편하게 쓸 수 있다.

val names = listOf("Amy", "Ben", "Chris") 
val result = names.filter { it.length <= 3 }.map { it.uppercase() } // ["AMY", "BEN"]

자바 컬렉션을 그대로 쓰되, 확장 함수 덕분에 처리 방식이 훨씬 깔끔해지는 느낌이다.

리플렉션을 쓰고 싶다면?

자바에서 리플렉션 쓰듯, 코틀린도 비슷하게 쓸 수 있다.
다만, kotlin-reflect 라이브러리를 추가해야 한다.

import kotlin.reflect.full.declaredMemberFunctions  
 
fun printAllFunctions(clazz: KClass<*>) {    
	clazz.declaredMemberFunctions.forEach {
		println(it.name) 
	} 
}

Gradle 설정은 이렇게 하면 된다:

	dependencies {     implementation("org.jetbrains.kotlin:kotlin-reflect") }

사용 후기

자바에서 코틀린으로 넘어오고 나서 가장 크게 느낀 건, 생산성과 안정성을 챙기겠다는 철학이 제대로 반영돼 있다는 거였다.
코드를 쓰는 것도 편해졌지만, 읽고 이해하는 데 드는 시간도 줄어들 것 같았다.

“이래서 다들 코틀린 쓰는구나” 싶었다. 간단하게 써본거라 직접 느끼진 못했지만, 단점은 없을지 찾아봤다. 역시 모든 기술이 그렇듯 단점도 있었다.

  • 추가 기능과 안정성 검사로 인해 빌드 속도는 상대적으로 느린 편
  • 자바와의 호환이 완벽하지는 않음
    • Kotlin 과 Java 를 혼용하며 Java 어노테이션 프로세서를 사용하고있다면 Kotlin 에서 읽지못하는 문제가 발생할 수 있다. (KAPT나 KSP로 해결 가능)
  • 팀 전체가 코틀린에 익숙하지 않으면 도입이 쉽진 않음

자바 개발자라면 코틀린은 한 번쯤 써봤으면 하는 매력적인 “실전형 언어”라고 생각한다.