1. 变量和常量
val
:不可变变量(只读,类似 final)
var
:可变变量
类型推断:Kotlin 支持自动推断变量类型
1 2 3 4 5 6 7 8 fun main () { val name = "Alice" var age = 25 age = 26 println("Name: $name , Age: $age " ) }
2. 基本数据类型
常见类型:Int
, Double
,
String
, Boolean
, List
,
Map
等
无基本类型与引用类型的区分,全部是对象
1 2 3 4 5 6 7 8 fun main () { val integer: Int = 42 val double: Double = 3.14 val text: String = "Kotlin" val isActive: Boolean = true println("Int: $integer , Double: $double , String: $text , Boolean: $isActive " ) }
3. 控制流:if 表达式
if
在 Kotlin 中是表达式,可以返回值
替代三元运算符(Kotlin 无三元运算符)
1 2 3 4 5 6 7 8 9 10 11 fun main () { val score = 85 val grade = if (score >= 90 ) { "A" } else if (score >= 80 ) { "B" } else { "C" } println("Score: $score , Grade: $grade " ) }
4. 控制流:when 表达式
类似 switch
,但更强大,支持多种条件
也是表达式,可返回值
1 2 3 4 5 6 7 8 9 10 fun main () { val day = 3 val dayName = when (day) { 1 -> "Monday" 2 -> "Tuesday" 3 -> "Wednesday" else -> "Unknown" } println("Day $day is $dayName " ) }
5. 循环
for
:用于迭代集合或范围
while
和 do-while
:与 Java 类似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun main () { println("Numbers 1 to 5:" ) for (i in 1. .5 ) { print("$i " ) } println() var count = 3 println("Counting down:" ) while (count > 0 ) { print("$count " ) count-- } }
6. 函数
使用 fun
关键字
支持默认参数、命名参数、单表达式函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 fun greet (name: String , greeting: String = "Hi" ) : String { return "$greeting , $name !" } fun sum (a: Int , b: Int ) = a + bfun apply (x: Int , op: (Int ) -> Int ) = op(x)fun double (x: Int ) : Int = x * 2 fun main () { println(greet("Alice" )) println(greet("Bob" , "Hello" )) println(sum(3 , 5 )) println(apply(5 ) { it * 2 }) println(apply(5 ) { x: Int -> x * 2 }) println(apply(5 , ::double)) }
7. 类和对象
使用 class
定义类
属性自动生成 getter/setter
支持构造函数、主构造函数、初始化块
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 31 32 33 class Person (val name: String) { private val secret = 42 protected val subclassVisible = "Protected" internal val moduleVisible = "Internal" var age: Int = 0 get () = field set (value) { if (value >= 0 ) field = value } init { println("Person created: $name " ) } constructor (name: String, age: Int ) : this (name) { this .age = age } fun introduce () { println("Hi, I'm $name , $age years old." ) } fun getAgeAfterYears (years: Int ) : Int { return age + years } } fun main () { val person = Person("Alice" , 25 ) person.introduce() println("Age in 5 years: ${person.getAgeAfterYears(5 )} " ) }
8. 继承和接口
默认类是 final
,需用 open
允许继承
接口使用 interface
,实现用 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 interface Animal { fun makeSound () } open class Pet (val name: String) class Dog (name: String) : Pet(name), Animal { override fun makeSound () { println("$name says Woof!" ) } } abstract class Shape { abstract fun area () : Double } class Circle (val radius: Double ) : Shape() { override fun area () = Math.PI * radius * radius } fun main () { val dog = Dog("Buddy" ) dog.makeSound() }
9. 空安全
可空类型用 ?
表示
安全调用 ?.
,Elvis 运算符 ?:
,非空断言
!!
1 2 3 4 5 6 7 8 9 10 11 fun main () { val nullableString: String? = null println("Length: ${nullableString?.length} " ) val length = nullableString?.length ?: 0 println("Length with Elvis: $length " ) }
10. 集合
支持 List
, Set
, Map
提供不可变和可变集合:listOf
,
mutableListOf
等
1 2 3 4 5 6 7 8 9 10 fun main () { val numbers = listOf(1 , 2 , 3 , 4 ) val mutableList = mutableListOf("apple" , "banana" ) val map = mapOf(1 to "one" , 2 to "two" ) println("Numbers: $numbers " ) mutableList.add("orange" ) println("Mutable List: $mutableList " ) println("Map: $map " ) }
11. Lambda 表达式和匿名函数
Lambda 语法:{ 参数 -> 表达式 }
常用于集合操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 fun main () { val numbers = listOf(1 , 2 , 3 , 4 , 5 ) val evenNumbers = numbers.filter { it % 2 == 0 } println("Even numbers: $evenNumbers " ) val squared = numbers.map { x -> x * x } println("Squared: $squared " ) val map = mapOf("a" to 1 , "b" to 2 ) map.forEach { key, value -> println("$key =$value " ) } val names = listOf("Tom" , "Alice" , "Bob" ) names.forEach(::println) val f1 = fun (x: Int ) : Int { return x + 1 } val f2 = { x: Int -> x + 1 } val f3 = { x: Int -> println(x + 1 ) } val f4 : (Int ) -> Unit = { x -> println(x + 1 ) } }
12. 扩展函数
1 2 3 4 5 6 7 8 9 10 11 12 13 fun String.reverse () : String { return this .reversed() } fun String.addExclamation () = "$this !" fun main () { val text = "Kotlin" println(text.reverse()) println("Hello" .addExclamation()) }
13. 数据类
使用 data class
自动生成 toString
,
equals
, hashCode
等,主构造函数至少一个参数,不可被 open
1 2 3 4 5 6 7 8 data class User (val name: String, val age: Int )fun main () { val user1 = User("Alice" , 25 ) val user2 = User("Alice" , 25 ) println("User1: $user1 " ) println(user.copy(name = "Bob" )) }
14. 协程
用于异步编程,需引入 kotlinx.coroutines
使用 launch
或 async
启动协程
1 2 3 4 5 6 7 8 9 10 11 12 13 import kotlinx.coroutines.*fun main () { val suspendFunc: suspend () -> Unit = { println("Suspended" ) } runBlocking { launch { delay(1000 ) println("Hello from coroutine!" ) } println("Main thread continues" ) } }
注意 :协程示例需要添加
kotlinx-coroutines-core
依赖到项目中,否则无法运行。
15. 对象声明
使用 object 创建单例
1 2 3 4 5 6 7 object Singleton { fun hello () = println("Hello" ) } fun main () { Singleton.hello() }
16. 伴生对象
在类中使用 companion object 定义静态成员
1 2 3 4 5 6 7 8 9 class MyClass { companion object { fun create () = MyClass() } } fun main () { val instance = MyClass.create() }
等价于
1 2 3 4 5 public class MyClass { public static MyClass create () { return new MyClass (); } }
17. 导入
1 2 3 4 import kotlin.math.PI as MathPIfun main () { println(MathPI) }
18. 异常处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun validate (x: Int ) { if (x < 0 ) throw IllegalArgumentException("Negative not allowed" ) } fun main () { val result = try { validate(-1 ) "Success" } catch (e: IllegalArgumentException) { println("Error: ${e.message} " ) "Failed" } finally { println("Cleanup" ) } println("Result: $result " ) }
19. 泛型
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 31 32 33 34 35 36 class Box <T >(val value: T) fun <T> printItem (item: T ) = println(item) interface Producer <out T > { fun produce () : T } class StringProducer : Producer <String > { override fun produce () = "Hello" } interface Consumer <in T > { fun consume (item: T ) } class AnyConsumer : Consumer <Any > { override fun consume (item: Any ) = println(item) } fun printList (list: List <*>) = println(list) fun main () { val intBox = Box(42 ) val strBox = Box("Kotlin" ) println("${intBox.value} , ${strBox.value} " ) printItem(42 ) printItem("Kotlin" ) val producer: Producer<String> = StringProducer() println(producer.produce()) val consumer: Consumer<Any> = AnyConsumer() consumer.consume("Hello" ) printList(listOf(1 , "A" )) }
20. 自定义注解
1 2 3 4 5 6 7 8 annotation class MyAnnotation (val priority: Int )@MyAnnotation(1) fun annotated () = println("Annotated" )fun main () { annotated() }
21. 中缀函数
1 2 3 4 5 infix fun Int .plus (x: Int ) = this + x fun main () { println(5 plus 3 ) }
22. 运算符重载
1 2 3 4 5 6 7 8 9 data class Point (val x: Int , val y: Int ) { operator fun plus (other: Point ) = Point(x + other.x, y + other.y) } fun main () { val p1 = Point(1 , 2 ) val p2 = Point(3 , 4 ) println(p1 + p2) }
23. 内联类(已废弃)
使用 inline class
定义单值包装类,编译时展开为原始类型,避免对象分配。
不支持接口实现。
使用 @JvmInline value class
替代
inline class
。
不可扩展,不可被集成。
1 2 3 4 5 6 inline class Name (val value: String)fun main () { val name = Name("Kotlin" ) println(name.value) }
内联类和内联值类特性:
❌ 继承类
不行,value class 不能继承任何类(除了 Any
)
❌ 被继承
不行,value class 自身也不能被继承
✅ 实现接口
可以实现接口
✅ 内联优化
可以提升性能,避免创建对象
24. 内联值类
场景:当需要包装单一值并保持性能(如
ID、计数、单位类型),使用内联值类;复杂对象仍使用普通
data class
。
为什么不直接使用原始类型?
内联值类为原始类型添加语义,防止误用。
代码可读性增加。
内联值类允许为原始类型添加方法或实现接口,封装特定逻辑,而不增加运行时开销。
领域驱动设计(DDD)。在复杂系统中,内联值类支持领域建模,用类型区分不同概念(如
OrderId
vs ProductId
),提高代码一致性。
内联值类可以在构造时验证值,防止非法状态,而原始类型无法限制。
内联值类通过 @JvmInline
在编译时替换为底层原始类型(如
Int
),几乎无额外内存或性能开销,接近直接使用原始类型的效率。
1 2 3 4 5 6 7 8 9 10 11 @JvmInline value class UserId (val id: Int ) : Comparable<UserId> { override fun compareTo (other: UserId ) : Int = id.compareTo(other.id) } fun main () { val userId = UserId(42 ) println(userId.id) println(userId > UserId(40 )) }
25. 无符号整数
UInt
:32 位无符号整数,ULong
:64 位,加
u
或 U
后缀。
编译为有符号整数,运行时模拟无符号行为。
1 2 3 4 5 fun main () { val uint: UInt = 42u val ulong: ULong = 123UL println("$uint , $ulong " ) }
26. SAM 转换改进
单方法接口支持 Lambda 转换
1 2 3 4 5 6 7 8 fun interface Action { fun run () } fun main () { val action = Action { println("Run" ) } action.run() }
27. 密封接口和密封类
sealed
修饰符表示
Expr
接口(或类)只能在同一模块(通常是同一文件或项目)内被实现。
外部代码无法创建新的Expr
子类,确保Expr
的所有可能实现(如Num
)是已知的。
对比普通接口,sealed
减少了运行时类型转换(如 as
Num)的需要。
意义:保证类型系统的封闭性,防止意外扩展,适合建模有限的类型集合(如表达式树)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 sealed interface Expr data class Num (val value: Int ) : Expr { operator fun plus (other: Num ) = Num(value + other.value) } data class Add (val left: Num, val right: Num) : Exprfun main () { val expr1: Expr = Num(42 ) println((expr1 as Num).value) val expr2: Expr = Add(Num(2 ), Num(3 )) println( when (expr2) { is Add -> (expr2.left + expr2.right) is Num -> expr2.value } ) }
Kotlin 的 密封类(sealed class)
是一种用于表示受限继承结构 的类,适合用来表达有限状态、事件、指令等类型的场景。sealed class
表示一个封闭的类层次结构 ,所有子类必须定义在同一个文件中。它是
抽象类 的一种变体,用于替代 enum 或 if/else
的分支判断 ,且能结合 when
表达式使用,非常强大。
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 31 32 33 34 35 36 sealed class Result <out T > { data class Success <out T >(val data : T) : Result<T>() data class Error (val exception: Throwable) : Result<Nothing >() object Loading : Result<Nothing >() } fun fetchData () : Result<String> { return try { val result = "Hello" Result.Success(result) } catch (e: Exception) { Result.Error(e) } } fun handle (result: Result <String >) { when (result) { is Result.Success -> println("Got data: ${result.data} " ) is Result.Error -> println("Error: ${result.exception.message} " ) Result.Loading -> println("Loading..." ) } } inline fun <T> Result<T> .onSuccess (action: (T ) -> Unit ) : Result<T> { if (this is Result.Success) action(data ) return this } inline fun <T> Result<T> .onError (action: (Throwable ) -> Unit ) : Result<T> { if (this is Result.Error) action(exception) return this } fetchData() .onSuccess { println("Success: $it " ) } .onError { println("Error: ${it.message} " ) }
👉 由于 Result
是密封类,when
表达式必须覆盖所有子类 ,否则编译报错(如果没有
else
分支)。
28. IO
1 2 3 4 5 import java.io.Filefun main () { File("test.txt" ).writeText("Hello" ) println(File("test.txt" ).readText()) }
29. 反射和运行时
需要在build.gradle.kts
文件中添加:
1 2 3 dependencies { implementation(kotlin("reflect" )) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 fun hello () = println("Hello" )data class Person (val name: String)fun main () { val ref1 = String::class println(ref1.simpleName) val ref2 = ::hello ref2() val props = Person::class .members println(props.map { it.name }) }
30. 属性委托
使用by
将属性委托给代理对象
lazy
首次访问时初始化,不可重新赋值。默认同步,需明确模式(如
LazyThreadSafetyMode.NONE
)。
Delegates.observable
:属性变化监听。
lazy
和 observable
是 Kotlin
提供的内置委托。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import kotlin.properties.Delegatesfun main () { val lazyVal: String by lazy { println("Computed" ) "Lazy" } println(lazyVal) println(lazyVal) var obsVal: String by Delegates.observable("Init" ) { property, old, new -> println("${property.name} : $old -> $new " ) } obsVal = "New" obsVal = "Final" }
31. 类委托
使用by
将接口实现委托给对象
组合优于继承,使用委托组合多个对象的行为
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 interface Printer { fun printMessage (message: String ) } class ConsolePrinter : Printer { override fun printMessage (message: String ) { println("Console: $message " ) } } class DelegatingPrinter (private val printer: Printer) : Printer by printer { override fun printMessage (message: String ) { println("Delegating: $message " ) printer.printMessage(message) } } fun main () { val consolePrinter = ConsolePrinter() val delegatingPrinter = DelegatingPrinter(consolePrinter) delegatingPrinter.printMessage("Hello, Kotlin!" ) }
32. 作用域函数
Kotlin 的作用域函数(Scope
Functions) 是让你能更优雅地处理对象初始化、配置、临时作用域和链式调用的语法工具。常用的有以下
5 个:
let
null安全、链式处理
Lambda结果
it
run
初始化 + 返回值
Lambda结果
this
with
多操作 + 返回值
Lambda结果
this
apply
初始化 + 返回对象
原对象
this
also
调试副作用 + 返回对象
原对象
it
🔹 1. let
:用 it
作为对象引用
适合做null 检查 和链式操作。
1 2 3 4 val name: String? = "Kotlin" name?.let { println("名字是 $it " ) }
🔹 2. run
:用 this
引用对象,返回表达式结果
适合对象初始化 + 返回值计算
1 2 3 4 5 val length = "Kotlin" .run { println("字符串是 $this " ) length } println(length)
🔹 3. with
:不是扩展函数,作用于已有对象
适合对对象做多个操作但不返回原对象 ,而是返回表达式值。
1 2 3 4 5 6 7 val sb = StringBuilder()val result = with(sb) { append("Hello, " ) append("World!" ) toString() } println(result)
🔹 4. apply
:用 this
,返回对象自身
适合构造对象并链式设置属性
1 2 3 4 5 6 7 8 data class User (var name: String = "" , var age: Int = 0 )fun main () { val user = User().apply { name = "124" age = 25 } }
🔹 5. also
:用 it
,返回对象自身
适合用于链式调用中插入副作用逻辑 (如日志、调试)
1 2 3 4 val list = mutableListOf(1 , 2 , 3 ) .also { println("原始列表: $it " ) } .apply { add(4 ) } .also { println("添加元素后: $it " ) }
33. 内联函数
inline
函数和 lambda 代码都在编译期被“展开复制”到调用处,提高性能
noinline
在 inline 函数中 ,禁止某个 lambda 被内联
crossinline
在 inline 函数中 ,禁止 lambda 使用
return
非局部返回
inline
✅ 1. inline
:让函数和 lambda “展开”
到调用处,提高性能
1 2 3 4 5 6 7 8 9 10 11 inline fun doSomething (block: () -> Unit ) { println("Before block" ) block() println("After block" ) } fun main () { doSomething { println("Doing work" ) } }
编译后近似于 👇:
1 2 3 4 5 fun main () { println("Before block" ) println("Doing work" ) println("After block" ) }
✅ 优点:消除函数调用开销、避免创建 Function
对象(尤其在频繁调用的 lambda 中)
noinline
⚠️ 2. noinline
:阻止某个 lambda
被内联(因为你可能要传递它)
1 2 3 4 5 6 7 8 inline fun doOps ( inlineBlock: () -> Unit , noinline logging: () -> Unit ) { inlineBlock() val func = logging func() }
你必须加 noinline
,否则无法将 lambda
存成变量或传给其他函数。
crossinline
🚫 3. crossinline
:禁止 lambda 用 return
做“非局部返回”
🔸 默认情况下,内联 lambda 可以直接
return
,但有风险。
1 2 3 4 5 6 7 8 9 10 11 inline fun higherOrder (block: () -> Unit ) { println("Before" ) block() println("After" ) } fun test () { higherOrder { return } }
要禁止这种“跳出上层函数”的行为,加 crossinline
:
1 2 3 4 5 6 7 inline fun higherOrder (crossinline block: () -> Unit ) { println("Before" ) val r = Runnable { block() } r.run() }
✅ 总结对照表
inline
将函数和 lambda 在调用处展开,提升性能、支持非局部 return
noinline
禁止某个 lambda 被内联(可传递为变量)
crossinline
禁止 lambda 使用非局部
return
(可用在回调、线程等)
📌 什么时候用它们?
高频调用、性能敏感的高阶函数
inline
lambda 需要传递或存为变量
noinline
lambda 不能用 return(如线程、回调)
crossinline