Kotlin 语法入门与快速上手
本文面向 Kotlin 小白,以及从 Java 转过来的 Android 开发。目标不是把 Kotlin 所有语法一次背完,而是让你能快速跑通基础写法,并理解它们为什么常出现在 Android 项目里。
怎么最快跑起来
方式一:Android Studio Scratch
- 打开 Android Studio。
- 选择
File -> New -> Scratch File -> Kotlin。 - 粘贴下面代码并运行。
kotlin
fun main() {
val name = "Android"
var count = 1
count += 1
println("Hello, $name")
println("count = $count")
}
方式二:新建一个普通 Kotlin 文件
如果项目已经启用了 Kotlin,可以在 app/src/main/java 或 app/src/main/kotlin 下新建 KotlinPractice.kt:
kotlin
package com.example.demo
fun main() {
println("Kotlin is ready")
}
方式三:在线跑
可以使用 Kotlin Playground,把本文代码块逐个粘贴进去运行。学习语法时,不必一开始就放进 Activity。
1. val 和 var
基础用法
val:只读变量,类似 Java 的final引用。var:可变变量,可以重新赋值。- Kotlin 推荐优先使用
val,只有确实需要变化时才用var。
kotlin
fun main() {
val userName = "Tom"
var age = 18
age = 19
println(userName)
println(age)
}
Java 对比
java
final String userName = "Tom";
int age = 18;
age = 19;
Android 常见用法
kotlin
class MainActivity : AppCompatActivity() {
private val adapter = UserAdapter()
private var selectedUserId: Long = -1L
}
adapter 创建后通常不需要换对象,用 val。selectedUserId 会随着点击变化,用 var。
2. 类型推断
基础用法
Kotlin 很多时候可以根据右边的值推断类型。
kotlin
val name = "Alice" // String
val count = 10 // Int
val price = 19.9 // Double
val enabled = true // Boolean
需要明确类型时,也可以写出来:
kotlin
val userId: Long = 1001L
val title: String = "Home"
伪代码
text
如果右侧值能推断类型:
编译器自动补全变量类型
否则:
开发者必须显式声明类型
Android 常见用法
kotlin
val intent = Intent(this, DetailActivity::class.java)
val titleView = findViewById<TextView>(R.id.titleView)
Intent(...) 的返回类型很明确,所以不需要重复写 Intent intent。
3. 字符串模板
基础用法
Kotlin 用 $变量名 或 ${表达式} 拼接字符串。
kotlin
fun main() {
val name = "Kotlin"
val version = 2
println("Hello, $name")
println("next version = ${version + 1}")
}
Java 对比
java
String name = "Kotlin";
System.out.println("Hello, " + name);
Android 常见用法
kotlin
textView.text = "用户:${user.name},年龄:${user.age}"
Log.d("User", "load user id = $userId")
4. 空安全 Null Safety
基础用法
Kotlin 默认变量不能为 null。
kotlin
val name: String = "Tom"
// name = null // 编译报错
var nickName: String? = null
String? 表示这个变量可能为 null。
常用操作符
kotlin
val length1 = nickName?.length // 安全调用,结果可能为 null
val length2 = nickName?.length ?: 0 // Elvis 操作符,给默认值
val length3 = nickName!!.length // 强制非空,null 时崩溃
伪代码
text
读取可能为空的对象:
如果对象不是 null:
调用它的方法或属性
否则:
返回 null 或默认值
Android 常见用法
kotlin
val title = intent.getStringExtra("title") ?: "默认标题"
supportActionBar?.title = title
从 Intent、Bundle、网络返回、数据库读取的数据都可能为空,Kotlin 空安全能把很多 NPE 提前变成编译期提醒。
5. 函数 Function
基础用法
kotlin
fun add(a: Int, b: Int): Int {
return a + b
}
fun printUser(name: String) {
println("user = $name")
}
单表达式函数可以简写:
kotlin
fun add(a: Int, b: Int) = a + b
默认参数和具名参数
kotlin
fun showToast(message: String, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(context, message, duration).show()
}
showToast(message = "保存成功")
showToast(message = "加载中", duration = Toast.LENGTH_LONG)
Java 对比
Java 常用方法重载解决默认参数:
java
void showToast(String message) {
showToast(message, Toast.LENGTH_SHORT);
}
void showToast(String message, int duration) {
...
}
Kotlin 用默认参数后,可以少写很多重载。
6. if 是表达式
基础用法
Kotlin 的 if 可以返回值。
kotlin
val score = 88
val result = if (score >= 60) {
"及格"
} else {
"不及格"
}
伪代码
text
如果条件成立:
result = A
否则:
result = B
Android 常见用法
kotlin
val visible = if (items.isEmpty()) View.GONE else View.VISIBLE
emptyView.visibility = visible
7. when
基础用法
when 类似 Java 的 switch,但更强大,也可以返回值。
kotlin
fun level(score: Int): String {
return when (score) {
in 90..100 -> "优秀"
in 60..89 -> "及格"
else -> "继续努力"
}
}
Android 常见用法
kotlin
when (view.id) {
R.id.saveButton -> save()
R.id.cancelButton -> finish()
}
处理 UI 状态:
kotlin
when (state) {
is UiState.Loading -> showLoading()
is UiState.Content -> showContent(state.data)
is UiState.Error -> showError(state.message)
}
8. 类和构造函数
基础用法
kotlin
class User(val id: Long, var name: String) {
fun printInfo() {
println("$id - $name")
}
}
使用:
kotlin
val user = User(1L, "Tom")
user.name = "Jerry"
user.printInfo()
Java 对比
java
class User {
private final long id;
private String name;
User(long id, String name) {
this.id = id;
this.name = name;
}
}
Kotlin 把构造函数、字段、getter/setter 合在一起写,代码更短。
Android 常见用法
kotlin
class UserRepository(private val api: UserApi) {
fun getUser(id: Long): User {
return api.getUser(id)
}
}
9. data class
基础用法
data class 适合表示数据对象,编译器会自动生成 equals()、hashCode()、toString()、copy() 等。
kotlin
data class User(
val id: Long,
val name: String,
val age: Int
)
fun main() {
val user = User(1, "Tom", 18)
val newUser = user.copy(age = 19)
println(user)
println(newUser)
}
Android 常见用法
kotlin
data class UserUiState(
val loading: Boolean = false,
val users: List<User> = emptyList(),
val errorMessage: String? = null
)
UI 状态、接口返回、数据库实体都很适合用 data class。
10. object 单例
基础用法
Kotlin 用 object 声明单例。
kotlin
object AppLogger {
fun log(message: String) {
println(message)
}
}
fun main() {
AppLogger.log("hello")
}
Java 对比
java
class AppLogger {
private static final AppLogger INSTANCE = new AppLogger();
static AppLogger getInstance() {
return INSTANCE;
}
}
Android 常见用法
kotlin
object UserSession {
var token: String? = null
fun isLogin(): Boolean {
return token != null
}
}
注意:单例会跟随进程存在,不适合随便持有 Activity,否则可能造成内存泄漏。
11. companion object
基础用法
companion object 类似 Java 里的静态成员。
kotlin
class DetailActivity : AppCompatActivity() {
companion object {
const val EXTRA_USER_ID = "extra_user_id"
fun createIntent(context: Context, userId: Long): Intent {
return Intent(context, DetailActivity::class.java)
.putExtra(EXTRA_USER_ID, userId)
}
}
}
使用:
kotlin
val intent = DetailActivity.createIntent(this, userId = 1001L)
startActivity(intent)
Android 常见用法
- 定义
Intent extrakey。 - 定义
Fragment.newInstance()。 - 放置常量、工厂方法。
12. 集合 List / Set / Map
基础用法
Kotlin 区分只读集合和可变集合。
kotlin
val names: List<String> = listOf("Tom", "Jerry")
val mutableNames: MutableList<String> = mutableListOf("Tom")
mutableNames.add("Jerry")
Map:
kotlin
val userMap = mapOf(
1L to "Tom",
2L to "Jerry"
)
val mutableMap = mutableMapOf<Long, String>()
mutableMap[1L] = "Tom"
伪代码
text
只读集合:
外部不能通过这个引用修改集合
可变集合:
可以 add/remove/put
Android 常见用法
kotlin
class UserAdapter : RecyclerView.Adapter<UserViewHolder>() {
private val users = mutableListOf<User>()
fun submitList(newUsers: List<User>) {
users.clear()
users.addAll(newUsers)
notifyDataSetChanged()
}
}
13. Lambda
基础用法
Lambda 是一段可以作为值传递的代码。
kotlin
val printer: (String) -> Unit = { message ->
println(message)
}
printer("hello")
集合操作:
kotlin
val users = listOf("Tom", "Jerry", "Alice")
val result = users.filter { name ->
name.length > 3
}
只有一个参数时可以用 it:
kotlin
val result = users.filter { it.length > 3 }
Android 常见用法
kotlin
button.setOnClickListener {
saveUser()
}
Java 匿名内部类:
java
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveUser();
}
});
Kotlin 简化后更适合写 UI 回调。
14. 扩展函数 Extension Function
基础用法
扩展函数可以给已有类"增加"函数,实际是静态方法语法糖。
kotlin
fun String.isPhoneNumber(): Boolean {
return this.length == 11 && this.all { it.isDigit() }
}
fun main() {
println("13800138000".isPhoneNumber())
}
Android 常见用法
kotlin
fun View.visible() {
visibility = View.VISIBLE
}
fun View.gone() {
visibility = View.GONE
}
loadingView.visible()
contentView.gone()
理解重点
扩展函数没有真的修改原类,也不能访问原类的 private 成员。它让工具方法写起来更贴近调用对象。
15. 作用域函数
Kotlin 常见作用域函数有 let、run、with、apply、also。
let:常用于非空处理和结果转换
kotlin
val title: String? = intent.getStringExtra("title")
title?.let {
textView.text = it
}
apply:常用于配置对象
kotlin
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("id", 1001L)
putExtra("name", "Tom")
}
also:常用于顺手做一件事,并返回原对象
kotlin
val user = User(1L, "Tom").also {
Log.d("User", "create $it")
}
记忆表
| 函数 | 作用域对象 | 返回值 | 常见用途 |
|---|---|---|---|
let |
it |
Lambda 结果 | 非空后执行、转换 |
run |
this |
Lambda 结果 | 计算一段结果 |
with |
this |
Lambda 结果 | 对已有对象批量操作 |
apply |
this |
原对象 | 初始化配置 |
also |
it |
原对象 | 打日志、附加动作 |
16. 智能类型转换
基础用法
Kotlin 使用 is 判断类型后,编译器会自动转换类型。
kotlin
fun printLength(value: Any) {
if (value is String) {
println(value.length)
}
}
Android 常见用法
kotlin
when (item) {
is TextItem -> showText(item.text)
is ImageItem -> showImage(item.url)
}
在 Java 中通常需要手动强转:
java
if (value instanceof String) {
String text = (String) value;
System.out.println(text.length());
}
17. 密封类 sealed class
基础用法
sealed class 适合表达有限种状态。配合 when 使用时,编译器能检查是否处理完整。
kotlin
sealed class UiState {
object Loading : UiState()
data class Content(val users: List<User>) : UiState()
data class Error(val message: String) : UiState()
}
fun render(state: UiState) {
when (state) {
UiState.Loading -> showLoading()
is UiState.Content -> showUsers(state.users)
is UiState.Error -> showError(state.message)
}
}
Android 常见用法
- 页面状态:Loading、Content、Empty、Error。
- 网络结果:Success、Failure、Loading。
- 列表 item 类型:Title、Content、Banner。
18. 接口和实现
基础用法
kotlin
interface UserRepository {
fun getUser(id: Long): User
}
class DefaultUserRepository(
private val api: UserApi
) : UserRepository {
override fun getUser(id: Long): User {
return api.getUser(id)
}
}
Java 转 Kotlin 重点
- Kotlin 继承类和实现接口都用
:。 - 重写方法必须写
override。 - 类默认不能被继承,需要
open。
kotlin
open class BasePresenter
class UserPresenter : BasePresenter()
Android 常见用法
Repository、UseCase、Navigator、Analytics 等都适合用接口隔离实现。
19. 泛型
基础用法
kotlin
class Box<T>(val value: T)
fun main() {
val intBox = Box(1)
val stringBox = Box("hello")
}
泛型函数:
kotlin
fun <T> firstOrNull(items: List<T>): T? {
return if (items.isEmpty()) null else items[0]
}
Android 常见用法
kotlin
abstract class BaseAdapter<T> : RecyclerView.Adapter<BaseViewHolder>() {
protected val items = mutableListOf<T>()
fun submitList(newItems: List<T>) {
items.clear()
items.addAll(newItems)
notifyDataSetChanged()
}
}
泛型能让通用组件复用,同时保留类型安全。
20. 委托属性 by
基础用法
Kotlin 的 by 可以把某些行为委托给另一个对象。
kotlin
val lazyValue: String by lazy {
println("init")
"Hello"
}
第一次访问时才初始化。
Android 常见用法
kotlin
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
}
by viewModels() 是 Jetpack 提供的属性委托,帮你从 ViewModelProvider 获取 ViewModel。
21. 解构声明
基础用法
data class 支持解构。
kotlin
data class User(val id: Long, val name: String)
fun main() {
val user = User(1L, "Tom")
val (id, name) = user
println(id)
println(name)
}
Android 常见用法
kotlin
val map = mapOf("id" to "1001", "name" to "Tom")
for ((key, value) in map) {
Log.d("Map", "$key = $value")
}
22. 异常处理
基础用法
Kotlin 没有受检异常,try 也可以作为表达式。
kotlin
val number = try {
"123".toInt()
} catch (e: NumberFormatException) {
0
}
Android 常见用法
kotlin
val result = runCatching {
api.loadUsers()
}.getOrElse {
emptyList()
}
网络请求、文件读取、JSON 解析都应该处理失败情况。
23. 协程 Coroutine 入门
基础概念
协程用于写异步代码。它不是线程,但可以挂起和恢复,让异步代码看起来像同步代码。
基础用法
kotlin
suspend fun loadUser(id: Long): User {
return api.getUser(id)
}
在 ViewModel 中调用:
kotlin
class UserViewModel(
private val repository: UserRepository
) : ViewModel() {
fun loadUser(id: Long) {
viewModelScope.launch {
val user = repository.getUser(id)
showUser(user)
}
}
}
伪代码
text
启动协程:
在后台等待网络结果
等结果回来后继续执行下一行
如果生命周期结束,取消任务
Android 常见用法
viewModelScope.launch {}:ViewModel 生命周期内执行任务。lifecycleScope.launch {}:Activity / Fragment 生命周期内执行任务。withContext(Dispatchers.IO) {}:切到 IO 线程做文件、数据库、网络操作。
24. Flow 入门
基础概念
Flow 是 Kotlin 协程里的异步数据流。它适合表示会持续变化的数据,比如数据库查询结果、搜索输入、页面状态。
kotlin
val nameFlow: Flow<String> = flow {
emit("Tom")
emit("Jerry")
}
收集数据:
kotlin
lifecycleScope.launch {
nameFlow.collect { name ->
textView.text = name
}
}
Android 常见用法
kotlin
class UserViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState
fun load() {
viewModelScope.launch {
_uiState.value = UiState.Content(repository.getUsers())
}
}
}
Fragment 中:
kotlin
viewLifecycleOwner.lifecycleScope.launch {
viewModel.uiState.collect { state ->
render(state)
}
}
25. Android 中的 Kotlin 最小实战
目标
写一个非常小的页面逻辑:点击按钮后加载用户,显示 Loading、成功或失败。
数据模型
kotlin
data class User(val id: Long, val name: String)
页面状态
kotlin
sealed class UserUiState {
object Loading : UserUiState()
data class Content(val user: User) : UserUiState()
data class Error(val message: String) : UserUiState()
}
Repository
kotlin
class UserRepository {
suspend fun getUser(id: Long): User {
delay(500)
return User(id = id, name = "Kotlin User")
}
}
ViewModel
kotlin
class UserViewModel : ViewModel() {
private val repository = UserRepository()
private val _uiState = MutableStateFlow<UserUiState>(UserUiState.Loading)
val uiState: StateFlow<UserUiState> = _uiState
fun loadUser(id: Long) {
viewModelScope.launch {
_uiState.value = UserUiState.Loading
_uiState.value = runCatching {
repository.getUser(id)
}.fold(
onSuccess = { UserUiState.Content(it) },
onFailure = { UserUiState.Error(it.message ?: "未知错误") }
)
}
}
}
Activity / Fragment 伪代码
kotlin
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
loadButton.setOnClickListener {
viewModel.loadUser(id = 1001L)
}
viewLifecycleOwner.lifecycleScope.launch {
viewModel.uiState.collect { state ->
when (state) {
UserUiState.Loading -> showLoading()
is UserUiState.Content -> showUser(state.user)
is UserUiState.Error -> showError(state.message)
}
}
}
}
}
这段代码串起来用了哪些基础语法
| 语法 | 出现位置 | 作用 |
|---|---|---|
data class |
User |
快速定义数据对象 |
sealed class |
UserUiState |
表达有限页面状态 |
suspend |
getUser() |
声明挂起函数 |
viewModelScope.launch |
loadUser() |
启动协程 |
StateFlow |
uiState |
暴露 UI 状态 |
| Lambda | setOnClickListener、collect |
写回调 |
when |
render state |
分发不同状态 |
| 空安全 | it.message ?: "未知错误" |
避免空指针 |
Java 转 Kotlin 常见坑
1. Kotlin 类默认不能继承
kotlin
open class BaseRepository
class UserRepository : BaseRepository()
2. Kotlin 变量默认非空
kotlin
var name: String? = null
不要一上来就写 !!,优先用 ?. 和 ?:。
3. == 比较内容,=== 比较引用
kotlin
val a = "Tom"
val b = "Tom"
println(a == b) // true
println(a === b) // 是否同一个对象引用
4. 集合只读不等于绝对不可变
kotlin
val list: List<String> = mutableListOf("A")
List 引用不能调用 add(),但底层对象可能仍然是可变集合。
5. 不要在 Activity 单例里持有 Context
kotlin
object BadHolder {
var activity: Activity? = null
}
这样可能导致内存泄漏。需要 Context 时,优先考虑 applicationContext 或短生命周期传参。
推荐学习顺序
- 先跑通
val、var、函数、字符串模板。 - 学会空安全:
?、?.、?:。 - 学会类、
data class、object、companion object。 - 学会集合和 Lambda,因为 Android 回调和列表数据天天用。
- 学会
when、sealed class,用来写页面状态。 - 最后再学协程和 Flow,把网络、数据库、UI 状态串起来。
小抄
| Java 写法 | Kotlin 写法 |
|---|---|
final String name = "Tom"; |
val name = "Tom" |
String name = null; |
var name: String? = null |
if (obj != null) obj.run(); |
obj?.run() |
condition ? a : b |
if (condition) a else b |
switch |
when |
| POJO | data class |
| static field / method | companion object |
| Singleton | object |
| anonymous listener | Lambda |
| utility method | extension function |
| async callback | coroutine / Flow |
结束语
Kotlin 的重点不是"语法更短",而是把空安全、函数式写法、状态表达、异步任务这些 Android 高频问题变得更清楚。刚开始不要追求一次掌握所有高级语法,能把页面状态、点击回调、列表数据、网络加载写顺,就已经能在 Android 项目里快速上手。