본문 바로가기
Backend/Kotlin

자바와 코틀린 기초 비교 - 변수부터 Null 안정성까지

by burning-man 2025. 5. 14.

개요

 

이번 스터디의 주제로 새롭게 진행할 토이 프로젝트의 언어를 코틀린으로 정하게 되었다.

자바에 익숙한 나는, 자바와 비교하면서 코틀린을 학습하면 더 빠르게 이해할 수 있을 것이라 판단했다.

그래서 이번 글에서는 코틀린의 기초 문법에서 변수 선언, 함수, 문자열 처리, 조건문, null 처리를 중심으로 자바와 코틀린을 비교하며 정리해보려한다.

 

1. 변수 선언 - val 과 var

val 과 var 를 보자마자 가장 먼저 떠오른건, 자바의 var 키워드와 자바스크립트의 val 였다.  

자바는 원시 타입(int, double..)과 참조 타입(Integer, Double)을 구분하지만, 코틀린에서는 모든 것이 객체처럼 동작한다. 또한 타입 추론을 지원하기 때문에 코드가 더 간결하다는 장점이 있다. 

 

Java Kotlin
int a = 10;
Integer b = 20;
val a = 10
val b = 20

 

  • val: 변경 불가능한 값 (자바의 final)
  • var: 변경 가능한 값
val pi = 3.14 // 변경 불가능한 값
val count = 0 // 변경 가능
count += 1

 

타입을 명시하고 싶으면 : 뒤에 타입을 적는다. 

val name: String = "버닝맨"

 

 

2. 함수 선언 - 간결함의 차이

자바에서는 함수 선언 시 public, 반환 타입, 메서드명 등 복잡한 구조를 사용하지만, 코틀린에서는 fun 키워드 하나로 시작하며, 반환 타입은 맨 뒤에 : 로 작성한다.

 

Java Kotlin
public String sayHi(String name) { return "Hi " + name}

fun sayHi(name: String): String = "Hi $name"

 

  • fun 키워드와 : 반환타입
// fun 키워드와 :반환타입
fun add(a: Int, b: Int): Int {
	return a + b
}

// 간결하게 return 생략
fun add(a: Int, b: Int) = a + b
  • 매개변수는 (이름: 타입) 순서
  • 반환 타입은 : 뒤에 작성
  • 한 줄일 경우 return 생략 가능

 

3. 문자열 템플릿 - 더 이상 '+' 는 없다

자바에서는 문자열을 합칠 때 '+' 를 사용하지만, 코틀린은 템플릿 문법으로 훨씬 깔끔하게 처리할 수 있다.

Java Kotlin
"이름은" + name + "입니다"
"길이: " + name.length()
"이름은 $name 입니다"
"길이: ${name.length}"

 

val name = "버닝맨"
val info = "안녕하세요, $name입니다."
val detail = "이름의 길이는 ${name.length}입니다."

 

4. 조건문 - 삼항 연산자? 필요 없음

자바에는 삼항 연산자가 있지만, 코틀린은 if 자체가 값을 반환하는 expression이기 때문에 삼항 연산자가 아예 존재하지 않는다.

val score = 84
val grade = if (score >= 90) "A" else "B"

 

  • when -  코틀린의 switch 업그레이드 
val grade = when(score) {
	in 90..100 -> "A"
    in 80..89 -> "B"
    else -> "F"
}
  • when은 범위, 조건, 타입 체크까지 가능
  • 자바의 switch-case 보다 훨씬 강력하고 표현력이 높음

 

5. Null 안전성 - 코틀린의 철학

자바에서는 개발자가 null 체크를 깜빡하고 안하게 되면 NullPointerException(NPE)이 발생한다. 

하지만 코틀린은 아예 문법 차원에서 nullable 변수와 non-null 변수를 명확하게 구분한다.

 

  • Null 처리 문법
    • ?.   - 안전한 호출 (null이면 호출하지 않고 null 반환)
    • ?:   - 엘비스 연산자 (null이면 기본값)
    • !!    - null이 아님을 강제 (예외 발생 위험)
    • let  - null이 아닌 경우에만 블록 실행 
val name: String? = null

val length = name?.length // null이면 null
val safeLength = name?.length ?: 0 // null이면 0 반환

name?.let {
	println("이름 길이: ${it.length}")
}

 

!! 연산자는 지양해야한다. 실제 서비스에서는 예상치 못한 NPE의 원인이 될 수 있다.

 

마무리

항목 Java Kotlin
변수 원시/참조 타입 구분, 타입 명시 타입 추론 가능, 모두 객체 취급
함수 접근자 + 반환타입 + 이름 fun + (파라미터: 타입): 반환타입
문자열 + $ 템플릿
조건문 삼항연산자 if 자체가 식, when 으로 확장
Null 명확한 구분 없음, 위험 문법적으로 Nullable 안전성 보장

 

  • 실습
fun main() {
	val userName: String? = "버닝맨"
    val userAge: Int = 20
    
    val nameLength = userName?.length ?: 0
    println("사용자 이름 길이: $nameLength")
    
    fun isAdult(age: Int): Boolean = age >= 20
    
    val ageStatus = if (isAdult(userAge)) "성인" else "미성년자"
    println("$username 님은 $ageStatus 입니다.")
    
    val ageGroup = when (userAge) {
    	in 0..12 -> "어린이"
        in 13..19 -> "청소년"
        in 20..60 -> "중장년"
        else -> "노년"
    }
    
    print("연령대 $userGroup")
}