우테코 과제를 하며 낯선 타입을 발견했다.

사용자가 입력하는 값은 제공된 유틸의 Console.readLine()을 활용하라고 명시되어 있었다.
Console.readLine() 으로 입력을 받으니 해당 변수의 타입이 String!으로 된 것을 확인할 수 있다.
엥 느낌표가 두 개도 아니고 한개라고?
💡 Java와 Kotlin의 차이
Kotlin은 null-safety를 언어 차원에서 보장한다.
즉, 컴파일 시점에 null 여부를 모두 검사한다.
반대로 Java는 Null Safety가 명시되지 않는다.
즉, Java 메서드의 매개변수나 반환값은 기본적으로 null일 수도 아닐 수도 있다.
따라서 Kotlin에서 Java 메서드를 사용할 때 그 값이 null인지 아닌 지 정확히 알 수 없다.
🔍 Console.readLine()을 살펴보자
//Console.java의 일부분
public static String readLine() {
return getInstance().nextLine();
}
private static Scanner getInstance() {
if (scanner == null) {
scanner = new Scanner(System.in);
}
return scanner;
}
- 핵심은
Console.readLine()은 자바의Scanner.nextLine()을 사용한다는 것이다.
✅ 즉 입력값이 null일지 아닐지 모른다는 것
→ 그렇다면 null Safety를 명시해야하는 kotlin에서 이러한 java 코드를 사용하면?

위에서 첨부했던 사진과 같이 String! 즉, 느낌표가 하나 붙는다.
그래서 느낌표 하나 붙는 건 무슨 타입인데?
플랫폼 타입(Platform type)
💡kotlin이 null 안전을 보장하지 않는 Java 타입
kotlin이 null 여부를 확실히 알 수 없는 Java 타입을 표현할 때 쓰는 중간 형태로
Kotlin과 Java 코드가 섞여 있을 때 등장하는 특수한 타입이다.
이 경우 개발자가 직접 책임지고 처리해야한다.
플랫폼 타입 처리하기
위에서 언급했던 Console.readLine()을 예로 들어보자.
1. non-null 연산자 사용
val input: String = Console.readLine()!!
pritnln("입력값: $input")
- null 타입이 들어올리 없다면 위와 같이 !!를 사용할 수 있다.
- 하지만 null이 들어오면 NullPointerException이 발생하기 때문에 null이 들어올 수 없는 상황에서만 사용해야 한다.
2. null을 허용하는 타입 명시
val input: String? = Console.readLine()
if (input != null) {
println("입력값: $input")
} else {
println("입력값 없음")
}
- 혹시 모를 null 가능성을 대비하기 위해 변수를 nullable로 선언한다.
- 가장 안정적이고 명시적인 방법이다.
3. 안전 호출(?.) 사용하기
Console.readLine()?.let { input ->
println("입력값: $input")
}
- 입력값이 null이라면 let 블럭이 실행되지 않기 때문에 안전하게 사용할 수 있다.
4. 엘비스 연산자(?:)로 기본값 지정하기
val input = Console.readLine() ?: "기본값"
println("입력값: $input")
- 입력값이 null일 때 기본값을 사용하고 싶다면 엘비스 연산자(?:)를 사용해 처리할 수 있다.
'학습 기록 > kotlin' 카테고리의 다른 글
| [Kotlin] LocalDate (java.time) (1) | 2025.12.04 |
|---|---|
| [Kotlin] groupBy, groupingBy (0) | 2025.12.03 |
| [Kotlin] Class - getter, setter (0) | 2024.10.29 |
| [Kotlin] Collection(List, Set, Map) (1) | 2024.10.27 |
| [Kotlin] 반복문(while, for) (1) | 2024.10.20 |
