Kotlin은 JetBrains가 개발하고 Google이 공식 지원하는 안드로이드 앱 개발 표준 언어입니다. 2011년 출시되어 Java의 단점을 보완하고 현대적인 프로그래밍 패러다임을 지원하는 언어로, 2019년부터 Google이 안드로이드 개발의 우선 언어로 지정했습니다. 간결한 문법, Null 안전성, 함수형 프로그래밍 지원으로 코드량을 줄이고 버그를 방지할 수 있어 개발 생산성이 크게 향상됩니다. Kotlin 기초 문법과 Java와의 차이점을 상세히 안내합니다.
Kotlin이란 무엇인가
Kotlin은 JVM(Java Virtual Machine) 위에서 동작하는 정적 타입 프로그래밍 언어입니다. Java와 100% 호환되어 기존 Java 라이브러리를 그대로 사용할 수 있으며, Java 코드와 Kotlin 코드를 같은 프로젝트에서 함께 사용할 수도 있습니다. 이러한 호환성 덕분에 기존 Java 프로젝트를 점진적으로 Kotlin으로 전환할 수 있어 학습 부담이 적습니다.
Kotlin의 가장 큰 장점은 간결성입니다. Java에 비해 코드량이 30~40% 적어 같은 기능을 더 짧은 코드로 구현할 수 있습니다. Boilerplate 코드(반복적으로 작성되는 형식적인 코드)가 대폭 줄어들어 개발 속도가 빨라지고 코드 가독성이 향상됩니다. 예를 들어 Java에서 getter/setter와 toString 메서드를 일일이 작성해야 하는 데이터 클래스를 Kotlin에서는 한 줄로 정의할 수 있습니다.
Kotlin은 현대적인 프로그래밍 기능을 지원합니다. 함수형 프로그래밍, 람다 표현식, 고차 함수가 기본 제공되며, 코루틴으로 비동기 프로그래밍을 간편하게 처리할 수 있습니다. Java도 버전 8부터 람다를 지원하지만 문법이 장황하고 제한적인 반면, Kotlin은 처음부터 함수형 프로그래밍을 염두에 두고 설계되어 더 직관적이고 강력합니다.
변수와 타입 선언
Kotlin에서 변수는 var(가변)와 val(불변) 두 가지 키워드로 선언합니다. var로 선언한 변수는 나중에 값을 변경할 수 있고, val로 선언한 변수는 한 번 할당하면 변경할 수 없습니다. val은 Java의 final 키워드와 유사하며, 불변 변수를 사용하면 예기치 않은 값 변경을 방지하여 버그를 줄일 수 있습니다. 일반적으로 val을 먼저 사용하고 필요할 때만 var로 변경하는 것이 권장됩니다.
타입 추론 기능으로 변수 타입을 명시하지 않아도 컴파일러가 자동으로 타입을 결정합니다. 예를 들어 “val name = "홍길동"” 같이 작성하면 컴파일러가 name 변수를 String 타입으로 인식합니다. 타입을 명시하고 싶다면 “val name: String = "홍길동"” 형식으로 작성할 수 있습니다. 타입 추론은 코드를 간결하게 만들어 주지만, 복잡한 경우에는 명시적으로 타입을 작성하는 것이 가독성에 도움이 됩니다.
Kotlin의 기본 타입에는 Int, Long, Float, Double, Boolean, String 등이 있습니다. Java와 달리 Kotlin에서는 모든 타입이 객체이며, int나 boolean 같은 원시 타입이 없습니다. 하지만 컴파일 시 성능을 위해 적절히 원시 타입으로 변환되므로 성능 저하는 없습니다. 문자열 템플릿 기능으로 “안녕하세요, $name님!” 같이 변수를 문자열 안에 직접 삽입할 수 있어 문자열 연결이 편리합니다.
Null Safety - 안전한 코드 작성
Kotlin의 가장 혁신적인 기능은 Null Safety입니다. Java에서 가장 흔한 에러인 NullPointerException을 언어 차원에서 방지하는 시스템으로, 변수를 선언할 때 null 값을 허용할지 명시해야 합니다. 일반 타입 선언 시에는 null을 할당할 수 없으며, null을 허용하려면 타입 뒤에 물음표를 붙여 “String?”처럼 nullable 타입으로 선언해야 합니다.
Nullable 변수에 접근할 때는 안전 호출 연산자 “?.”를 사용합니다. 예를 들어 “name?.length”는 name이 null이 아니면 length를 반환하고, null이면 null을 반환합니다. 이 방식으로 null 체크를 간결하게 처리할 수 있으며, if-else로 null을 검사하는 Java 방식보다 훨씬 편리합니다. 엘비스 연산자 “?:”를 사용하면 null일 때 기본값을 지정할 수 있습니다. “name?.length ?: 0”은 name이 null이면 0을 반환합니다.
Not-null assertion 연산자 “!!”도 있지만 사용을 자제해야 합니다. “name!!”은 name이 절대 null이 아니라고 단언하는 것인데, 실제로 null이면 NullPointerException이 발생합니다. 이 연산자는 확실히 null이 아닌 경우에만 사용하고, 대부분의 경우 안전 호출 연산자나 엘비스 연산자를 사용하는 것이 안전합니다. Null Safety는 초보자에게 처음에는 불편하지만, 익숙해지면 버그를 크게 줄여주는 강력한 기능입니다.
함수와 제어문
Kotlin에서 함수는 fun 키워드로 정의합니다. “fun add(a: Int, b: Int): Int { return a + b }” 형식으로 작성하며, 함수명 뒤 괄호 안에 매개변수와 타입을 명시하고 콜론 뒤에 반환 타입을 작성합니다. 함수 본문이 한 줄이면 중괄호를 생략하고 “fun add(a: Int, b: Int) = a + b” 형식으로 간결하게 작성할 수 있습니다. 반환 타입이 Unit(Java의 void)이면 생략 가능합니다.
제어문은 if, when, for, while이 있으며, Java와 유사하지만 더 강력합니다. if문은 표현식으로 동작하여 값을 반환할 수 있습니다. “val result = if (score > 80) "Pass" else "Fail"” 같이 작성하면 조건에 따라 값을 할당할 수 있어 삼항 연산자가 필요 없습니다. when문은 Java의 switch문보다 강력하며, 여러 조건을 쉽게 처리할 수 있습니다. “when (x) { 1 -> "One" 2 -> "Two" else -> "Other" }” 형식으로 작성합니다.
for문은 범위 연산자와 함께 사용하면 편리합니다. “for (i in 1..10)” 은 1부터 10까지 반복하며, “for (i in 1 until 10)”은 1부터 9까지 반복합니다. 컬렉션을 순회할 때는 “for (item in list)”처럼 간단하게 작성할 수 있습니다. while문은 Java와 동일하게 동작하며, “while (조건) { 코드 }” 형식으로 사용합니다.
클래스와 데이터 클래스
Kotlin의 클래스는 class 키워드로 정의하며, 생성자를 클래스명 옆에 바로 작성할 수 있습니다. “class Person(val name: String, var age: Int)” 형식으로 선언하면 생성자와 프로퍼티가 동시에 정의됩니다. Java처럼 필드를 선언하고 생성자를 별도로 작성할 필요가 없어 코드가 간결해집니다. val로 선언하면 읽기 전용 프로퍼티, var로 선언하면 읽기/쓰기 프로퍼티가 됩니다.
데이터 클래스는 data class 키워드로 정의하며, 데이터를 저장하는 용도의 클래스를 쉽게 만들 수 있습니다. “data class User(val name: String, val age: Int)” 같이 작성하면 equals, hashCode, toString, copy 메서드가 자동으로 생성됩니다. Java에서 수십 줄로 작성해야 하는 코드가 한 줄로 줄어드는 것입니다. 데이터 클래스는 불변 객체로 만드는 것이 권장되므로 프로퍼티는 val로 선언하는 것이 좋습니다.
상속은 Java와 유사하지만 기본적으로 모든 클래스가 final입니다. 상속을 허용하려면 open 키워드를 붙여야 하며, “open class Animal” 같이 선언합니다. 인터페이스는 interface 키워드로 정의하며, 클래스에서 콜론으로 구현합니다. “class Dog : Animal(), Runnable” 형식으로 상속과 인터페이스 구현을 함께 작성할 수 있습니다. 기본적으로 클래스를 final로 만든 것은 의도치 않은 상속을 방지하여 코드 안정성을 높이기 위함입니다.
Java와 Kotlin 차이점
Java와 Kotlin의 가장 큰 차이는 문법의 간결성입니다. Java에서 클래스를 만들 때 필요한 getter/setter, toString, equals 같은 메서드를 Kotlin은 자동으로 생성해줍니다. 세미콜론도 생략할 수 있어 코드가 깔끔하며, 타입 추론 덕분에 타입 선언을 생략할 수 있는 경우가 많습니다. 이러한 특징들이 모여 전체 코드량을 30~40% 줄여주며, 개발 속도와 유지보수성을 크게 향상시킵니다.
Null 처리 방식도 큰 차이입니다. Java는 런타임에 NullPointerException이 발생하여 앱이 강제 종료되는 경우가 많지만, Kotlin은 컴파일 시점에 null 가능성을 체크하여 사전에 버그를 방지합니다. 안전 호출 연산자와 엘비스 연산자로 null을 우아하게 처리할 수 있어 방어적 코딩이 편리합니다. 이 기능만으로도 앱의 안정성이 크게 향상됩니다.
함수형 프로그래밍 지원도 차이점입니다. Kotlin은 람다, 고차 함수, 확장 함수를 기본 제공하며, 컬렉션 처리가 매우 편리합니다. “listOf(1, 2, 3).map { it * 2 }” 같은 코드로 리스트의 모든 요소를 2배로 만들 수 있으며, Java보다 훨씬 간결하고 직관적입니다. 코루틴으로 비동기 처리도 쉽게 할 수 있어 복잡한 비동기 코드를 간단하게 작성할 수 있습니다.
자주 묻는 질문 (FAQ)
❓ Kotlin을 배우기 전에 Java를 먼저 배워야 하나요?
아니요, Kotlin은 Java 없이도 바로 배울 수 있습니다. Kotlin이 Java보다 문법이 간결하고 직관적이어서 초보자가 더 쉽게 배울 수 있습니다. Java를 알면 Kotlin 전환이 쉽지만, Java를 모르더라도 Kotlin부터 시작하는 것이 더 효율적입니다. 최신 안드로이드 개발은 Kotlin을 우선하므로 Kotlin부터 배우는 것을 권장합니다.
❓ Kotlin을 배우는 데 얼마나 걸리나요?
프로그래밍 경험이 있다면 기본 문법은 1~2주, 실전 활용까지는 1~2개월 정도 소요됩니다. Java 개발자라면 2~4주면 Kotlin으로 전환할 수 있습니다. 완전 초보자는 3~6개월 정도 꾸준히 학습하면 간단한 앱을 만들 수 있는 수준에 도달할 수 있습니다.
❓ Kotlin과 Java를 함께 사용할 수 있나요?
네, Kotlin은 Java와 100% 호환되어 같은 프로젝트에서 함께 사용할 수 있습니다. 기존 Java 코드를 유지하면서 새로운 코드만 Kotlin으로 작성할 수 있어 점진적으로 전환할 수 있습니다. Android Studio는 Java 코드를 Kotlin으로 자동 변환하는 기능도 제공합니다.
❓ Null Safety가 불편한데 꼭 사용해야 하나요?
처음에는 불편하지만 Null Safety는 Kotlin의 가장 큰 장점입니다. NullPointerException을 사전에 방지하여 앱 안정성을 크게 높여줍니다. 익숙해지면 자연스럽게 사용할 수 있으며, 버그를 줄여주는 강력한 기능입니다. 안전 호출 연산자와 엘비스 연산자를 활용하면 편리하게 처리할 수 있습니다.
❓ Kotlin으로 안드로이드 외에 다른 것도 개발할 수 있나요?
네, Kotlin은 서버 개발(Spring, Ktor), iOS 앱(Kotlin Multiplatform Mobile), 웹 개발(Kotlin/JS), 데스크톱 앱(Kotlin/Native) 등 다양한 플랫폼에서 사용할 수 있습니다. 하나의 언어로 여러 플랫폼을 개발할 수 있어 생산성이 높으며, 특히 Kotlin Multiplatform으로 Android와 iOS 앱을 동시에 개발할 수 있습니다.