일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- oracle 18c
- Oracle Express Edition
- 오라클 캐릭터셋 변경
- Oracle 테이블 띄어쓰기
- Oracle 테이블 대소문자
- 비전공자를 위한 데이터베이스 입문
- Oracle 초기 사용자
- Oracle 사용자명
- oracle
- Orace 18c
- Oracle 18c HR schema
- 오라클 캐릭터셋 확인
- ORA-12899
- 윈도우 Oracle
- Oracle 윈도우 설치
- ORA-00922
- 무료 오라클 데이터베이스
- 서평단
- Oracle 18c HR
- Oracle 사용자명 입력
- ora-01722
- 무료 오라클 설치
- Oracle 18c 설치
- 오라클 캐릭터셋 조회
- Today
- Total
The Nirsa Way
[Kotlin] 코틀린 변수와 타입, Null 처리 연산자 정리 본문
※ 해당 코틀린 포스트들은 기본적으로 자바를 알고 있다는 가정하에 간단히 예제만 제공하여 설명됩니다.
코틀린이란?
코틀린은 JetBrains에서 만든 JVM 언어로써 JVM 위에서 동작하기 때문에 Java와 100% 상호작용이 가능합니다. 그렇기에 코틀린에서 자바 클래스를 호출하는 방식도 가능하며 일반적인 자바와 똑같이 소스 파일(.kt) → 컴파일(Bytecode) → 클래스 파일(.class)이 생성이 됩니다.
자바에 비해 간결한 코드, 불변 보장, 타입 추론 생략, Null-Safe, 함수형 프로그래밍 지원 등의 이유로 최근 코틀린을 사용하는 기업들이 많이 늘어난 추세입니다.
// Kotlin
fun main() {
println("Hello, Kotlin!")
}
// Java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
변수와 타입
우선 코틀린의 변수 선언부터 확인해보면 아래와 같습니다. val와 var로 나눠지며 불변 선언(변경 X)과 가변 선언(변경 O)으로써 나뉘어 집니다. 코틀린에서 val은 자바의 final 이며, var은 자바의 일반 변수들을 생각하시면 됩니다. 또한 각각의 문법에 세미콜론이 붙지 않는 것을 확인할 수 있습니다.
// Kotlin
fun main() {
val name = "Nirsa" // 불변(val)
var age = 20 // 가변(var)
}
// Java
public class Hello {
public static void main(String[] args) {
final String name = "Nirsa"; // 불변(final)
int age = 20; // 가변(일반 변수)
}
}
위의 값들은 읽기 전용(val), 읽기/쓰기 전용(var)이므로 자바의 static final같은 상수의 경우 const val을 사용하여 적용할 수 있습니다. 상수는 오로지 읽기만 가능해야 하므로 val 하고만 함께 사용이 가능합니다.
const val NAME = "Nirsa"
코틀린에서 사용되는 기본 타입은 아래와 같습니다.
- Any : 모든 클래스의 최상위 타입, 어떠한 타입이든 담을 수 있음
- Byte : 정수형
- Short : 정수형
- Int : 정수형
- Long : 정수형
- Float : 실수형
- Double : 실수형
- Boolean : 논리형
- Char : 문자형
- String : 문자열
그 외 반환 값 없음(Unit, 자바의 void), 어떠한 값도 담지 않음(Nothing, 예외를 던질 경우 즉 호출된 위치로 돌아가지 않음) 등이 있습니다.
또한 코틀린과 자바의 차이점으로는 코틀린에서는 기본형과 래퍼 클래스의 구분이 없습니다. 문법상 모든 타입을 객체처럼 취급(Int, Double, Float, ...)하며 자동으로 기본형으로 변환이 됩니다.
그렇기에 코틀린에서 타입을 아래와 같이 작성하면 되며 JVM에서 자동으로 기본형으로 최적화되기 때문에 타입을 명시할 때 기본형과 래퍼 클래스 사용으로 인한 성능 저하를 걱정하지 않아도 됩니다. (단, 해당 내용은 이후 아래의 'Null 처리 연산자' 주제의 1번과 내용이 이어집니다)
fun main() {
val name : String = "Nirsa"
var age : Int = 20
}
만약, 타입을 명시하지 않는다면 해당 변수가 초기화될 때 리터럴을 기준으로 어떠한 타입으로 넣을 지 결정됩니다. "Nirsa"라는 문자열 리터럴이라면 String으로 타입이 추론 및 결정되며, 20 이라는 정수형 리터럴이라면 Int로 타입이 추론 및 결정되게 됩니다.
val name = "Nirsa" // → String으로 추론
val age = 20 // → Int로 추론
val price = 12.5 // → Double로 추론
val isActive = true // → Boolean으로 추론
Null 처리 연산자
코틀린의 강력한 기능중 하나인 Null 처리 연산자 입니다. Java의 경우 Optinal이나 다른 유틸/코드를 작성하여 null 처리를 해주어야 하는 반면, 코틀린은 기본적으로 제공해주는 Null 처리 연산자를 통해 훨씬 간결하고 강력하게 처리할 수 있습니다.
1. 연산자 ? (nullable)
변수로 사용 가능한 ? 연산자 입니다. 명시한 타입 뒤에 ?를 작성한다면 이 값은 null이 들어올 수 있음을 의미합니다. 타입을 명시만 한 경우 기본적으로 null 불가(non-nullable) 입니다.
그렇다면 null 불가일 때는 무조건 ?를 붙이는게 좋으냐에 대해서는 한번 고민해봐야 할 주제입니다. 코틀린의 경우 nullable 연산자(?)를 사용할 경우 기본적으로 boxing이 발생하며 자바의 래퍼클래스처럼 객체 형태로 존재하게 됩니다. 기본형은 null을 가질 수 없기 때문에 nullable 연산자(?)를 사용하게 되면 기본적으로 null을 가질 수 있는 래퍼 클래스로 처리하게 되는 것 입니다.
fun main() {
val age: Int = null // [에러] null 불가(non-nullable), 기본형
val name: String? = null // null 가능(nullable), 래퍼 클래스
}
2. 연산자 ?. (Safe Call)
연산자 ?. 는 null이 아닐 때 해당 메서드를 호출할 수 있도록 도와주는 연산자 입니다. 아래의 코드를 확인해보면 name이 null이 아닐때만 length를 호출해주는 역할을 수행합니다. length가 호출되지 않았으므로 NPE가 발생하지 않고 name의 값인 null이 출력됩니다.
fun main() {
val name: String? = null
val length = name?.length
println(length) // null
}
3. 연산자 ?: (Elvis)
연산자 ?: 는 null이면 기본값을 적용하도록 도와주는 연산자 입니다. 아래의 코드를 실행하면 name은 null 이므로 기본값 "Nirsa"를 적용합니다.
fun main() {
val name: String? = null
val length = name ?: "Nirsa" // name 변수의 값이 null 이므로 기본값 "Nirsa" 저장
println(length) // Nirsa 출력
}
만약 해당 값이 null이 아니라면 원래의 값을 반환 합니다.
fun main() {
val name: String? = "Not Null"
val length = name ?: "Nirsa" // name 변수의 값이 null 이 아니므로 기본값을 저장하지 않음
println(length) // Not Null 출력
}
4. 연산자 !! (Not-Null 단정), 사용 권장 X
연산자 !!는 무조건 이 값은 null이 아님을 단정지으며 null이 아님을 강제로 보장합니다. 만약 아래의 코드와 같이 name의 변수가 null임에도 !!를 사용하면 NPE가 발생합니다.
fun main() {
val name: String? = null
val length = name!!.length // [NPE 발생] Not-Null 단정
println(length)
}
5. 연산자 as? (Safe Cast)
연산자 as? 는 캐스팅이 실패하면 null을 반환하도록 합니다. 아래의 코드처럼 Any 타입으로 먼저 받은 후 null이 아닐 경우 String 타입으로 캐스팅되게끔 작성할 수 있도록 도와줍니다.
fun main() {
val name: Any = "Nirsa"
val cast = name as? String
println(cast)
}
6. let 블록 (null-safe 실행 블록)
현재 사이드 프로젝트를 진행하며 생각보다 많이 마주쳤던 let 블록 입니다. null이 아닐때만 블록을 실행하는 함수입니다. 해당 블록 안에서는 대상 객체(name)를 it라는 이름으로 참조하게 됩니다.
fun main() {
val name: String? = "Nirsa"
name?.let {
println(it) // Nirsa 출력
println(it.length) // 5 출력
}
}
아래와 같이 name이 null이 아닐때만 let 블록을 사용하고, 마지막 표현식 결과(it.length)를 반환하여 변수에 넣어 사용할 수도 있습니다.
fun main() {
val name: String? = "Nirsa"
val result = name?.let {
println(it) // Nirsa 출력
println(it.length) // 5 출력
it.length // 마지막 표현식 결과 반환(return)
}
println(result) // 5
}
또한 it가 아닌 다른 변수명으로 사용하고 싶다면 아래와 같이 사용하여 이름을 변경하고 사용할 수 있습니다.
fun main() {
val name: String? = "Nirsa"
val result = name?.let { n ->
println(n)
println(n.length)
n.length
}
println(result)
}
'Development > Kotlin' 카테고리의 다른 글
[Kotlin] 람다(Lambda)와 고차 함수(Higher-Order Function) 예시 (0) | 2025.08.22 |
---|---|
[Kotlin] 데이터 클래스, 오브젝트 클래스(data class, object class) (0) | 2025.08.22 |
[Kotlin] 상속과 오버라이딩 (open, override) (2) | 2025.08.22 |
[Kotlin] 클래스와 생성자(생성자 실행 순서, 주 생성자, 보조 생성자, init 블록) (0) | 2025.08.22 |
[Kotlin] 코틀린 기본 문법 (if, when, for, white, 함수 선언과 호출) (0) | 2025.08.22 |