변수, 타입, 연산자
작성
Java 코드를 Kotlin 으로 옮기며 단계(step)마다 .java 와 .kt 를 나란히 두고 비교한 기록이다. 이 노트는 step 01(변수), 04(연산자), 05(제어문)에서 적은 것이다.
변수
fun main() {
val num1 = 10L // val num1: Long = 10L 과 같다. 타입을 추론한다.
val num2 = 10L
var num3: Long? = 1_000L // null 이 들어갈 수 있으면 타입 뒤에 ? 를 붙인다.
val num4 = num1 + num2 // + num3 은 타입 불일치로 컴파일이 안 된다.
num3 = 2_000_000L
num3 = null
val person = Person("junha") // new 를 쓰지 않는다.
println(person.name)
}
- 타입을 적지 않아도 추론한다.
val은 Java 의final처럼 다시 대입할 수 없고,var는 대입할 수 있다.- 기본적으로 모든 변수에 null 을 넣을 수 없게 설계되어 있다. nullable 이면
Long?처럼 명시한다. nullable 타입은 아예 다른 타입으로 취급되어서Long과 더할 수 없다. - 원시 타입(primitive)과 참조 타입을 구분하지 않는다. 모든 타입을 객체로 다루고, 연산할 때는 알아서
long으로 바꿔 계산한다. 오토박싱과 언박싱을 Kotlin 이 처리한다. - 객체를 만들 때
new를 쓰지 않는다. - 문자열은 Java 와 같이 큰따옴표를 쓴다.
- 파일 이름과 클래스 이름이 같을 필요가 없다. 한 파일에 클래스와 함수를 여러 개 둘 수 있다.
- 같은 패키지 안에 있으면 import 하지 않아도 된다.
보일러플레이트가 사라진다
class Person(var name: String)
Java 에서 필드, 생성자, getter, setter 를 적던 클래스가 한 줄이 된다. getter 와 setter 는 자동으로 만들어진다.
바이트코드로 확인하기
IntelliJ 에서 Tools → Kotlin → Show Kotlin Bytecode → Decompile 을 누르면 Kotlin 코드가 어떤 Java 코드로 바뀌는지 볼 수 있다. 위 한 줄짜리 Person 이 getter 와 setter 를 가진 Java 클래스로 풀리는 것을 눈으로 확인할 수 있다.
연산자
val money1 = JavaMoney(1_000L)
val money2 = JavaMoney(2_000L)
if (money1 < money2) {
println("money1 < money2")
}
- Java 와 달리 객체를 비교 연산자로 비교하면 자동으로
compareTo()를 호출한다. - 동등성(equality)은 두 객체의 값이 같은지 묻는 것이고
==를 쓴다. 동일성(identity)은 두 객체가 같은 객체인지, 즉 주소가 같은지 묻는 것이고===를 쓴다.
제어문
fun validateScoreIsNotNegative(score: Int) {
if (score < 0) {
throw IllegalArgumentException("${score} cannot be smaller than 0")
}
}
fun getPassOrFail(score: Int): String {
return if (score > 50) {
"P"
} else {
"F"
}
}
if-else가 값이 되는 expression 이라 바로return할 수 있다.- 문자열 안에
${score}로 값을 끼워 넣는다. - 예외는
new없이throw IllegalArgumentException(...)으로 던진다.