#!if top1 != null && 문서명1 == null
[DEPRECATED] top1 파라미터는 더 이상 사용되지 않습니다! 대신 문서명1 파라미터를 사용해 주세요.
#!if top1 == null && 문서명1 != null
[[Kotlin|Kotlin]]
프로그래밍 언어 문법 | |
{{{#!folding [ 펼치기 · 접기 ] {{{#!wiki style="margin: 0 -10px -5px; word-break: keep-all" | 프로그래밍 언어 문법 C(포인터 · 구조체 · size_t) · C++(클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python(함수 · 모듈) · Kotlin · MATLAB · SQL · PHP · JavaScript(표준 내장 객체) · Haskell(모나드) · 숨 |
마크업 언어 문법 HTML · CSS | |
개념과 용어 함수(인라인 함수 · 고차 함수 · 콜백 함수 · 람다식) · 리터럴 · 문자열 · 식별자(예약어) · 상속 · 예외 · 조건문 · 반복문 · 비트 연산 · 참조에 의한 호출 · eval · 네임스페이스 · 호이스팅 | |
기타 #! · == · === · deprecated · GOTO · NaN · null · undefined · 배커스-나우르 표기법 | }}}}}} |
프로그래밍 언어 목록 · 분류 · 문법 · 예제 |
1. 개요
Kotlin(코틀린)의 문법을 설명하는 문서다.==# 편집 지침 #==
소스 코드로 예시를 들 때 아래와 같이 문법을 활용하여 소스 코드를 써 주시기 바랍니다.
\#!syntax kotlin (소스코드) |
또한 메인함수에서 매개변수가 필요한 경우 통일을 위해 args를 사용하시기 바랍니다.
예시 코드는 아래와 같습니다.
#!syntax kotlin
fun main(args: Array<String>) {
println("Hello, World!")
}
2. 기본
코틀린의 주목적은 현재 자바가 사용되고 있는 모든 용도에 적합하면서도 더 간결하고 생산적이며 안전한 대체 언어를 제공하는 것이다. 1장 코틀린이란 무엇이며, 왜 필요한가? 코틀린은 개발자를 더 행복하게 하기 위해 고안된 모던하면서도 성숙한 프로그램언어 입니다. 간결하고 안전하며 Java 및 기타 언어와 상호 운용 가능하며 생산적인 프로그래밍을 위해 여러 플랫폼 간에 코드를 재사용할 수 있는 다양한 방법을 제공합니다. 원문: Kotlin is a modern but already mature programming language designed to make developers happier. It's concise, safe, interoperable with Java and other languages, and provides many ways to reuse code between multiple platforms for productive programming. Get started with Kotlin |
코틀린의 코드는 객체 지향을 원칙으로 하며, 자바와 100% 연계되는 문법을 사용하고 있다.[1]
.kt, 스크립트의 경우 .kts의 확장자를 가진다.
상술했듯 자바와 굉장히 비슷한 문법 구조를 가지고 있어 이 문서를 읽기 전에 Java/문법 문서를 읽으면 큰 도움이 된다.
3. 파일 구조
[package 이름 명시][import할 패키지 명시]
[클래스 구현, 변수 및 함수 선언]
Java와 다른점은 다음과 같다.
- 패키지를 실제 파일의 경로와 동일하게 명시할 필요가 없다. 다만, 일관성을 위해 동일하게 명시하는 것을 추천한다.
- 하나의 파일이 여러개의 public class를 가질 수 있다. 비슷하게 파일 이름에 제한이 없다.[2]
- top-level에 변수와 함수를 선언할 수 있다.
4. 메인 함수
#!syntax kotlin
fun main(args: Array<String>) {
println("Hello, World!")
}
Java와 비교하면 메인 함수의 길이가 상당히 짧다.
#!syntax kotlin
fun main() {
println("Hello, World!")
}
Kotlin 1.3 버전부터는 매개변수를 생략할 수 있다.
5. 제어자
5.1. 접근 제어자
자바와 다르게 기본값이 public이다.- public: 공개. 어디에서나 접근 가능하다.
- Internal: 내부. 코틀린에 새로 추가된 제어자로, 동일 모듈[3]에서만 접근 가능하다.
- protected: 보호. 해당 클래스나 파일에서만 접근 가능하지만, 상속 관계라면 외부에서도 접근 가능하다.
- private: 비공개. 해당 클래스나 파일에서만 접근 가능하다.
자바의 접근 제어자와 차이가 있어, 자바와 코틀린을 함께 사용할 때 접근 범위에 차이가 생긴다.
- 코틀린에서 자바 코드 사용
- default: 코틀린에서는 private-package 개념이 없어. private로 취급된다.
- protected: 코틀린의 접근 범위가 적용되어 상속 관계가 아니면 접근할 수 없다.
- 자바에서 코틀린 코드 사용
- internal: public으로 취급하지만 권장되지 않는다. 경고를 하는 IDE도 있다.
- protected: 자바의 접근 범위가 적용되어 동일 패키지라면 사용 가능하지만, 권장되지 않는다. 이 역시 경고를 하는 IDE도 있다.
5.2. 기타 제어자
- final, open: 수정 가능. 기본값은 final이며 기본값이 다르다는걸 제외하면 자바와 동일하다.
- abstract: 추상. 자바와 동일하다. 추상 클래스는 open이 자동으로 적용된다.
- override: 재정의. 자바에서는 동일한 이름, 매개변수를 가지면 재정의되었고, 어노테이션을 사용해 명시했다면 코틀린에서는 제어자를 사용해야 한다.
- lateinit: 초기화 지연. 변수의 초기화 시점을 지연한다. 상수와 자바의 원시 타입에 대응되는 타입에는 사용할 수 없다.
- const: 상수. 원시 타입 또는 String 타입인 val 키워드로 선언된 상수에 사용 가능하며, 자바의 static final로 컴파일된다.
- data: 데이터. 클래스에 사용 가능하며, 필드에 대해 equals, hashCode, toString 등의 메서드를 자동으로 생성한다.
- infix: 객체 a에 대해 하나의 매개 변수 m을 받는 메서드에 사용 가능하다. 메서드 이름을 method라고 할 때 호출을
a.method(b)
대신a method b
로 호출할 수 있다. - operator: 해당 메서드가 연산자를 정의하는 메서드임을 알린다. 이는 자바에서 원시 타입과 String에서만 사용 가능한 연산자를 다른 객체에서 사용할 수 있게 된다. 예를 들어 + 연산자는 plus()메서드를 호출하고, 이 메서드를 정의하면 다른 객체에서 + 연산자를 쓸 수 있다
6. 타입
Kotlin에는 원시 타입[4]과 그 래퍼 클래스[5]가 구분되지 않고 모든 타입이 참조 자료형으로 취급되고, 컴파일 시 가능한 경우 원시 타입으로 변환된다. 원시 타입은 Immutable Type[6]으로 처리되며, 값 변경 시 실제로는 그 값에 대응되는 객체가 대입된다.아래 타입들은 Java에서 사용하는 Primitive Type과 대응된다. Primitive Type이 그렇듯, 이 타입에 속하는 객체는 모두 immutable이다.
- 부호 있는 정수:
Long
(long
) >Int
(int
) >Short
(short
) >Byte
(byte
) - 실수:
Double
(double
) >Float
(float
) - 논리:
Boolean
(boolean
) - 문자:
Char
(char
)
아래 타입들은 Java에서 Primitive Type으로 취급되지 않는다. Java의 Primitive 타입과 마찬가지로 immutable이다.
- 문자열:
String
- 객체:
Any
, 최상위 클래스로, Java의Object
에 대응된다.[7]
아래는 Java에는 없는 Kotlin 오리지널 타입이다. 이 쪽도 immutable.
- 부호 없는 정수:
ULong
[8] >UInt
[9] >UShort
[10] >UByte
[11] - 유닛:
Unit
, Java의void
메서드가 Kotlin에서는 이 객체를 반환하는 메서드로 바뀐다. 싱글톤 객체.[12] - 무(無):
Nothing
, 최하위 클래스로Unit
을 포함해 어떠한 값도 반환할 일이 없을 때에만 쓰인다.[13] Java의Void
클래스와 동등하게, 이 타입은 객체 생성이 불가능하다.
배열 타입은 아래와 같이 정의된다.
*Array
는 제너릭 타입인 Array<*>
와 다르다는 점에 유의. 확장 함수를 통해 변환할 수는 있다. 위의 것들과는 달리 mutable인데, 이는 Java에서도 그렇다.- 부호 있는 정수의 배열:
LongArray
[14],IntArray
[15],ShortArray
[16],ByteArray
[17] - 부호 없는 정수의 배열:
ULongArray
,UIntArray
,UShortArray
,UByteArray
- 실수 배열:
DoubleArray
[18],FloatArray
[19] - 논리 배열:
BooleanArray
[20] - 문자 배열:
CharArray
[21] - 일반 배열:
Array<T>
,Nothing
은 사용할 수 없다.[22]
7. 변수 선언
#!syntax kotlin
package HelloWorld;
fun main() {
var a1: Int = 1
var a2 = 1
var b: String = "1"
val c: Double = 3.141592
println(a1) // OK
println(b) // OK
println(c) // OK
a1 = a1 ++ // OK
b = b + "2" // OK
c = c ++ // ERROR
}
타입을 적어줘도, 적어주지 않아도 된다. var이 아니라 val로 쓰게 된다면 c = c ++과 같이 그 값을 바꾸지 못한다. 기본적으로는 val을 쓰는게 좋은 습관이며 권장된다. 하지만 자바에서 final을 잘 쓰지 않듯이 어차피 대부분 var로 바꿀거 코틀린에서도 var로 코딩 하는 사람도 적지 않다. 다만 val을 블록 안에 쓰면 블록 범위 안에서만 동작하므로 run {} 같은 블록 안에 val을 써서 val의 동작 범위를 정해줄 수도 있다.
7.1. 특이한 경우: null check
#!syntax kotlin
package HelloWorld;
fun main() {
var a: Int? = 1
var b: Int? = 1
println(a !! + b !!)
var c: Int? = null // OK
var d: Int = null // ERROR
}
기본적으로 ?를 타입 뒤에 붙이면 null을 사용할 수 있다. 하지만 둘 다 null 선언이 된 상태에서 값을 수정하거나 출력하려 하면 null check 에러가 뜨는 경우가 있다. 이런 경우에는 !!를 붙여주면 해결되는 경우도 있다.
7.2. 특이한 경우: 형변환 하기
#!syntax kotlin
package HelloWorld;
fun main() {
val a: Int = 1
val b: String = "1"
println(a + b) // ERROR
println(a + b.toInt()) // OK
val c: Int = 1
val d: String = "1"
println(c + d!!.toInt()) // OK
}
String과 Int를 더하려면 오류가 나기 때문에 .to타입()을 붙여 타입을 변경할 수 있다. null check를 하는 경우 d!!.toInt()로 해주면 된다.
8. 함수
#!syntax kotlin
package HelloWorld;
fun main() {
// TODO
var Method: Method = Method()
Method.Method1() // OK
Method.Method2() // OK
}
class Method() {
fun Method1() {
println("Hello")
}
open fun Method2() {
println("Hello")
}
}
함수에 대한 기본개념이 있다면 어떻게 사용하는지 문법만 배우면 된다.
계속 Method라는 얘기가 나오는데 클래스의 이름을 Method로 할 필요는 없다.
8.1. 확장 함수
이미 선언되어있는 객체나 클래스 하위의 함수를 재정의하거나 새로 정의할 수도 있다.#!syntax kotlin
package HelloWorld
fun String.sayHello() {
println("Hello, $this") // this는 객체 String을 가리킴
}
fun main() {
"NamuWiki".sayHello() // "Hello, NamuWiki" 출력
}
8.2. infix 함수
infix 키워드를 이용해서 .과 ()를 쓰지 않아도 되는 함수를 만들 수 있다.infix 함수의 조건으로는
- 확장 함수 또는 클래스 함수여야 한다
- 매개 변수 1개여야 한다
- 매개 변수는 기본 값이 없으면서 vararg 매개변수가 없어야 한다
#!syntax kotlin
package HelloWorld;
import java.net.*
class Human(var name: String, var age: Int, var location: String) {
fun travel(location: String) {
this.location = location
}
override fun toString(): String {
return "${name}, ${age}세, ${location} 거주"
}
infix fun eat(food: String) = println("${this.name}님이 ${food}를 먹었습니다.")
}
fun main() {
Human("홍길동", 30, "서울") eat "피자" // 홍길동님이 피자를 먹었습니다.
Human("홍길동", 30, "서울") browse URL("https://namu.wiki/") // 홍길동님이 https://namu.wiki/를 검색했습니다.
}
infix fun Human.browse(url: URL) = println("${this.name}님이 ${url}를 검색했습니다.")
9. 스코프 함수
9.1. let
객체에 대해서 람다식 수행하고, 블록의 마지막 문장 실행 결과를 반환한다. 자기 자신을 참조할 때에는it
을 기본으로 사용하며, 이는 변경이 가능하다. (이는 it
을 사용하는 다른 스코프 함수에도 동일하다.)let이 있는 버전
#!syntax kotlin
package HelloWorld;
class Human(var name: String, var age: Int, var location: String) {
fun travel(location: String) {
this.location = location
}
override fun toString(): String {
return "${name}, ${age}세, ${location} 거주"
}
}
fun main() {
Human("홍길동", 30, "서울").let {
println(it)
it.travel("부산")
println(it)
} // 마지막 println()의 결과인 Unit이 반환됨
}
let이 없는 버전
#!syntax kotlin
package HelloWorld;
class Human(var name: String, var age: Int, var location: String) {
fun travel(location: String) {
this.location = location
}
override fun toString(): String {
return "${name}, ${age}세, ${location} 거주"
}
}
fun main() {
val human = Human("홍길동", 30, "서울")
println(human)
human.travel("부산")
println(human)
}
let을 사용하는 경우
- null이 가능한 오브젝트가 null이 아닐 때 코드를 실행하게 할 때
{{{#!folding [ 예시 ]
#!syntax kotlin
package HelloWorld;
val humans = ArrayList<Human>()
class Human(var name: String, var age: Int, var location: String) {
fun travel(location: String) {
this.location = location
}
override fun toString(): String {
return "${name}, ${age}세, ${location} 거주"
}
}
fun main() {
Human("홍길동", 30, "서울").let {
humans.add(it)
}
// ?. 연산자를 사용, getHuman()의 결과가 null이라면 람다식이 무시되고 null이 반환된다.
getHuman("홍길동")?.let {
println(it.name)
}
}
fun getHuman(name: String): Human? {
return humans.firstOrNull {
it.name == name
}
}
}}}
- 특정 변수를 제한적인 블록에서만 접근하게 만들 때
9.2. run
run
은 let
과 비슷하나 자신을 참조할 때 it
대신 this
를 쓴다는 점이 다르다. let
과 마찬가지로 마지막 실행 결과가 반환된다.#!syntax kotlin
fun main() {
Human("홍길동", 30, "서울").run {
println(this)
this.travel("부산")
println(this)
} // 마지막 println()의 결과인 Unit이 반환됨
}
run
는 Top-level에서 사용할 수도 있다. 객체 내에서 run
을 사용할 때 객체 자신을 가리키지 않은 것과 동일하다. 객체 안에 있지 않으므로 객체 자신을 가리키는 this
는 사용할 수 없다.#!syntax kotlin
fun main() {
run { // Top-level이므로 this 키워드 사용 불가
val human = Human("홍길동", 30, "서울")
println(human)
human.travel("부산")
println(human)
} // 마지막 println()의 결과인 Unit이 반환됨
}
9.3. also
also
는 let
과 달리 자기 자신을 반환한다. let
의 마지막 문장으로 it
을 쓴 것과 동일하다.#!syntax kotlin
fun main() {
Human("홍길동", 30, "서울").also {
println(this)
this.travel("부산")
println(this)
} // Human 객체가 그대로 반환됨
}
9.4. with
with
는 run
의 일반 함수 버전으로, with(receiver, transform)
은 receiver.run(transform)
과 동일한 효력을 갖는다. Top-level에서 사용할 수 있으며, 자기 자신 참조는 this
를 사용한다.#!syntax kotlin
fun main() {
with(Human("홍길동", 30, "서울")) {
println(this)
this.travel("부산")
println(this)
} // 마지막 println()의 결과인 가 그대로 반환됨
}
9.5. apply
apply
는 run
과 달리 자기 자신을 반환한다. run
의 마지막 문장으로 this
를 쓴 것과 동일하다.#!syntax kotlin
fun main() {
Human("홍길동", 30, "서울").also {
println(this)
this.travel("부산")
println(this)
} // Human 객체가 그대로 반환됨
}
9.6. takeIf
람다식에 명세된 조건을 만족하는 경우 자기 자신을, 그렇지 않으면null
을 반환한다. 자기 자신은 it
으로 가리킨다.#!syntax kotlin
fun main() {
val human = Human("홍길동", 30, "서울").also {
this.travel("부산")
}.takeIf {
it.location == "서울"
}
println(human) // it.location == "서울"이 false이므로 null 출력
}
9.7. takeUnless
람다식에 명세된 조건을 만족하는 경우null
을, 그렇지 않으면 자기 자신을 반환한다. 자기 자신은 it
으로 가리킨다.#!syntax kotlin
fun main() {
val human = Human("홍길동", 30, "서울").also {
this.travel("부산")
}.takeUnless {
it.location == "서울"
}
println(human) // it.location == "서울"이 false이므로 "홍길동, 30세, 부산 거주" 출력
}
10. 입력 받기
10.1. readLine / readln
#!syntax kotlin
package HelloWorld
fun main() {
println("이름을 입력하세요")
var name: String? = readLine()
// 또는
// var name: String? = readln()
println("${name}님 안녕하세요!")
}
한 줄을 입력받는다.
10.2. Scanner
#!syntax kotlin
package HelloWorld
import java.util.*
fun main() {
val scanner = Scanner(System.`in`)
println("이름을 입력하세요")
var name: String = scanner.nextLine()
println("나이를 입력하세요")
var age: Int = scanner.nextInt()
println("이름 : ${name}, 나이 : ${age}")
}
자바와 다른점이 System.`in`인데, Kotlin에서 in은 예약어이기 자바에서 쓰는 in은 ``으로 감싸서 사용한다.
next타입()으로 다른 타입들도 사용할 수 있다.
11. 출력하기
#!syntax kotlin
package HelloWorld;
fun main() {
print("안녕") // 1
println("하세요") // 2
var Hello: String = "안녕하세요"
println(Hello) // 3
var World1 : String = "안녕"
var World2 : String = "하세요"
println("${World1 + World2}")
println(World1 + World2) // 4
}
네 가지 경우 모두 안녕하세요가 출력된다. print인 경우는 줄바꿈을 하지 않는다. C언어를 예로 들자면 printf("hello world!\\n"); 에서 \\n이 생략된 격이다. 이 말은 즉슨 println의 경우에는 \\n이 자동으로 삽입되어 있다는 뜻이다. 물론 \\n 사용이 불가능 한 것은 아니다. 다만 println이 쓰이는데 \\n까지 같이 쓴다면 두줄 줄 바꿈이 된다.
12. 배열
12.1. Array
Array를 만들 때는 이와 같이 하면 된다#!syntax kotlin package HelloWorld;
fun main() {
val doubleArray: Array<Double> = arrayOf(1.0, 1.5, 2.0, 3.0)
}
위의 경우 arrayOf 안에 있는 값을 가져가서 Array가 그 값들의 type을 가지게 된다.
12.2. List
13. 반복문
13.1. for문
#!syntax kotlin
package HelloWorld
fun main () {
for (i in 0 .. 5) {
println("안녕하세요")
}
for (i in 1 .. 6) {
println("안녕하세요")
}
for (i in 1 until break) {
println("안녕하세요")
}
}
첫번째와 두번째 경우 둘 다 안녕하세요가 6번 출력된다. 반쯤 람다식이라고 볼 수 있는데, 기존 Java와 절차지향 언어인 C언어에서 쓰였던 var i = 0; i < 10; i ++ 같은 문법 대신 눈물나게 간결한 문법을 제공한다.
세번째 경우인 until의 경우에는 저 자체로는 굉장히 불완전한 코드이다. until을 이용해서 break까지, 변수 a의 값이 5가 될때 까지등 여러 가지 조건을 내걸어 반복문을 사용 할 수 있다.
이중 반복문을 사용하려는 경우 첫번째 반복문에 변수로 i를 지정해주었다면 두번째 반복문에는 i를 사용하면 안된다. 코드 안에서 내부적으로 i를 여러번 반복하고 그 반복 안에 새로운 i가 있는 형식이기 때문이다. 여러 IDE에서 실행을 해보면 빨간색 밑줄 또는 노란색 밑줄이 그어지면서 this variable is already defined같은 오류가 뜬다.
13.2. while문
14. 제어문
14.1. if[else]
if (expression) statement1 [else statement2]
() 속의 조건식(expression)이 참이 되면 statement1을, 거짓이면 statement2를 실행하는 구조로 되어 있다. else 이하는 생략 가능하며 else 뒤에 if를 다시 사용하여 if ... else if ... else if ... else 와 같이 사용할 수도 있다.
#!syntax kotlin
package HelloWorld;
fun main() {
var a = 1
var b = 1
if(a == b) {
// TODO
} else {
// TODO
}
}
14.2. when
자바의 switch 문이랑 비슷하지만 더 많은 기능을 가졌다.#!syntax kotlin
package HelloWorld;
fun main() {
var a = 1
when(a) {
1 -> println("a는 1입니다")
5 -> println("a는 5입니다")
7, 9 -> println("a는 7 아니면 9입니다")
in 10..100 -> println("a는 10 이상 100 이하입니다")
else -> println("a는 그 외입니다")
}
// "a는 1입니다" 가 출력됨.
}
또한 when 자체를 값으로 사용할 수 있다. 밑에 있는 코드는 위랑 같은 결과를 보여준다.
#!syntax kotlin
package HelloWorld;
fun main() {
var a = 1
println(when(a) {
1 -> "a는 1입니다"
5 -> "a는 5입니다"
7, 9 -> "a는 7 아니면 9입니다"
in 10..100 -> "a는 10 이상 100 이하입니다"
else -> "a는 그 외입니다"
})
}
15. 상속
한 객체가 다른 객체를 상속할 때에는 다음과 같은 형태를 띈다.#!syntax kotlin
open class ParentClass()
class ChildClass: ParentClass()
코틀린은 다른 프로그래밍 언어나 자바와 달리 더 이상 상속하지 못하는 final이 클래스의 기본값이다
따라서 이 클래스를 상속가능하게 하고싶다면
open
(상속 선택)이나 abstract
(상속 필수)를 붙여서 다른 클래스가 해당 클래스를 상속할 수 있도록 해주어야 한다한 객체가 인터페이스를 구현할 때에는 다음과 같은 형태를 띈다.
#!syntax kotlin
interface SampleInterface()
class ChildClass: SampleInterface
16. 람다식
16.1. 기본
다음과 같이 활용한다.- 함수형
{{{#!syntax kotlin
package Kotlin
fun fn(a:Int, b:Int):Int {return a+b}
println(fn(1,2))
}println(fn(1,2))
}}}
- 람다식
{{{#!syntax kotlin
package Kotlin
val fn = {a:Int, b:Int -> a+b}
println(fn(1,2))
}println(fn(1,2))
}}}
16.2. 고차함수
코틀린은 인터페이스를 통해서 함수를 인자로 넘겨주던 Java와 다르게 아주 간편하게 함수를 주고받거나 반환할 수 있다.- 함수를 인자로 받기
{{{#!syntax kotlin
package Kotlin
println("$a 와 $b 를 함수에 -> ${f(a, b)}")
}}}}
* 함수를 반환하기
{{{#!syntax kotlin
* 함수를 반환하기
{{{#!syntax kotlin
package Kotlin
fun getPrintingFunction(str: String): () -> Unit {
return { println(str) }
}}}}
또한, 함수(람다식)을 인자로 넘겨주는 함수를 사용할 경우, 함수의 내용을 소괄호 밖에 표시하는 것이 권장된다.
#!syntax kotlin
printer(3, 5, {i, j -> i + j}) // 작동
printer(3, 5) {i, j ->
i + j
} // 작동
이와 앞서 언급한 클래스 내 함수 삽입을 이용하면 context를 만들 수 있다.
#!syntax kotlin
package HelloWorld;
object NamuWiki {
fun getDocument(name: String): String {
// TODO
}
}
fun <T> namuWiki(lambda: NamuWiki.() -> T) : T { // lambda는 Namuwiki 하위 함수
return NamuWiki.lambda()
}
fun main() {
val kotlin: String = namuWiki { // returns result of getDocuent()
getDocument("Kotlin/문법") // getDocument under context namuWiki
}
getDocument("Kotlin/문법") // ERROR: function getDocument doesn't exist
println(kotlin)
}
[1] 실제로 IntelliJ IDEA나 안드로이드 스튜디오 등에서 자바 코드를 넣으면 자동으로 코틀린으로 변환해 준다.[2] Java에서는 파일 이름과 주요 클래스의 이름이 동일해야한다.[3] 한번에 컴파일되는 단위.[4] Java의 int, double, char 등 소문자로 시작하는 타입[5] Integer, Double, Character 등 원시 타입을 참조 타입으로 변환한 클래스[6] 내부의 값을 변경할 수 없는 타입,
String
등이 대표적이다.[7] 단, KClass
등 일부 제너릭에서는 Any
와 Object
를 명확하게 구분짓기도 한다. 이 때는 <T: Any>
등으로 명시해야 한다.[8] 8바이트, Java에 대응되는 타입이 없다.[9] 4바이트, Java에 대응되는 타입이 없다.[10] 2바이트, Java에 대응되는 타입이 없다.[11] 1바이트, Java에 대응되는 타입이 없다.[12] Unit?
로 쓰면 값으로 Unit
또는 null
만 사용할 수 있다.[13] 주로 무한 루프나 throw
등에 사용한다. 나아가 Nullable로 사용(Nothing?
)하면 null
이외의 다른 값은 사용할 수 없다.[14] Java의 long[]
에 대응, Long[]
(=Array<Long>
)과는 다르다.[15] Java의 int[]
에 대응, Integer[]
(=Array<Int>
)과는 다르다.[16] Java의 short[]
에 대응, Short[]
(=Array<Short>
)과는 다르다.[17] Java의 byte[]
에 대응, Byte[]
(=Array<Byte>
)과는 다르다.[18] Java의 double[]
에 대응, Double[]
(=Array<Double>
)과는 다르다.[19] Java의 float[]
에 대응, Float[]
(=Array<Float>
)과는 다르다.[20] Java의 boolean[]
에 대응, Boolean[]
(=Array<Boolean>
)과는 다르다.[21] Java의 char[]
에 대응, Character[]
(=Array<Char>
)과는 다르다.[22] 배열 내에 null
값만 들어가 있어도 Nothing?
으로는 사용할 수 없고, 반드시 자료형을 nullable로 명시해야 한다.