第 1 篇|Kotlin 基础入门 ------ 变量、函数与空安全
哈喽,各位零基础想入门 Android 开发的小伙伴们~ 今天咱们正式开启 Kotlin 学习之旅的第一篇,聚焦 Android 开发的核心基础:变量、函数,并且重点攻克让无数新手头疼又绕不开的「空安全」机制。
很多新手刚接触 Android 开发,都会纠结同一个问题:先学 Java 还是 Kotlin?这里直接给结论------学 Android,首选 Kotlin,也只能是 Kotlin。无论从 Google 官方的战略导向,还是实际开发效率来看,Kotlin 早已是 Android 开发的绝对主流。学会它,你才能跟上当下的开发节奏。接下来,咱们一步步拆解,从最基础的语法到核心重难点,全程附上可运行的代码示例,保证新手也能零门槛上手。
一、为什么学 Android 首选 Kotlin?
在 Android 开发领域,Kotlin 早已不是"选修课",而是"必修课"。核心原因可以归结为两点:官方全力支持 + 语言本身降维打击级别的优势,双buff加持,让 Kotlin 成为 Android 新手的最优选择。
1. Google 官方的"亲儿子"待遇
自 2017 年 Google I/O 大会宣布 Kotlin 成为 Android 官方一级开发语言后,Google 便坚定推行「Kotlin-first」战略,全方位资源都在向 Kotlin 倾斜,具体体现在三个方面:
-
开发工具优先:Android Studio 的新建项目模板默认语言就是 Kotlin,Java 模板反而需要手动切换,可见官方对 Kotlin 的优先级倾斜;
-
新框架 Kotlin 独占:Android 最新的声明式 UI 框架 Jetpack Compose 仅提供 Kotlin DSL 支持,未来趋势不言而喻,不学 Kotlin 就无法掌握最新开发技术;
-
官方文档与课程:官方开发者网站上的代码示例、Codelab 实战教程,绝大多数都优先展示 Kotlin 版本,Java 仅作为历史技术栈补充。
简单说:现在出去面试 Android 岗,招聘 JD 里几乎清一色要求"熟练掌握 Kotlin"。不学 Kotlin,相当于输在了起跑线上。
2. Kotlin 对比 Java 的核心优势(新手直观对比)
Kotlin 基于 JVM(Java 虚拟机),能与 Java 代码 100% 互通,但它完美解决了 Java 的诸多历史遗留痛点,对新手更友好、写起来也更高效,两者核心对比如下:
| 对比维度 | Java | Kotlin |
|---|---|---|
| 代码简洁度 | 极度啰嗦,写一个简单的数据类需要手写构造、getter/setter 等几十行代码 | 一行搞定,data class User(val name: String) |
| 空指针安全 | 编译期不设防,运行时空指针(NPE)是头号崩溃元凶 | 类型系统天生区分可空与非空,编译期就能拦截 90% 的 NPE |
| 函数式编程 | 支持有限,且在低版本 Android 上受限 | 天生支持高阶函数、Lambda 表达式,集合操作极其流畅 |
| 异步处理 | 回调地狱,代码难以阅读和维护 | 内置协程,用同步的写法写出异步的逻辑,代码清晰优雅 |
结论:对新手而言,Kotlin 的上手难度并不比 Java 高,甚至因为语法糖丰富,写起来更轻松。更重要的是,学会 Kotlin 能帮你从根源上减少 App 崩溃,开发效率直接翻倍,是 Android 入门的最优解。
二、第一个 Kotlin 程序:从 Hello World 开始
实践出真知,学习任何编程语言,都要从"Hello World"开始。咱们用 Android Studio(后简称 AS)来编写第一个 Kotlin 程序,全程实操,新手跟着做就能成功。
1. 准备工作
打开 AS,点击 New Project → Empty Views Activity,在 Language 选项里确保选的是 Kotlin(通常默认就是),其他选项保持默认,点击 Finish,AS 会自动生成好项目结构,无需手动配置。
2. 编写第一个 main 函数
Kotlin 程序的入口是 main 函数,语法比 Java 更简洁。我们在项目里新建一个 Kotlin File(右键包名 → New → Kotlin Class/File,选择 File),命名为 FirstProgram,输入以下代码(含详细注释,新手可直接复制):
kotlin
// 单行注释:这是 Kotlin 程序的入口函数
fun main() {
/*
多行注释:
println 输出内容后会自动换行
print 输出内容后不会自动换行
*/
println("Hello Kotlin! 我是 Android 新手~")
print("这是不换行的输出,")
print("这一句会和上一句连在一起。\n") // \n 是换行转义符
println("程序运行结束!")
}
3. 运行验证与补充知识点
点击代码行号左侧的绿色三角箭头,选择 Run。等待编译完成后,在 AS 底部的 Run 面板中,你会看到如下输出:
plain
Hello Kotlin! 我是 Android 新手~
这是不换行的输出,这一句会和上一句连在一起。
程序运行结束!
恭喜!你的第一个 Kotlin 程序成功运行🎉。这里补充两个新手必知的小知识点,帮你夯实基础:
-
main 函数的另一种形式:支持接收命令行参数,写法为 fun main(args: Array<String>),新手暂时用不到,了解即可;
-
注释规范:// 是单行注释,/* ... */ 是多行注释,注释不会被编译执行,但好的注释习惯能让你的代码更好懂,新手一定要养成写注释的习惯。
三、变量声明:val 和 var 的核心区别(新手必分清)
变量是程序中存储数据的容器,Kotlin 声明变量只有两个关键字:val 和 var,核心区别在于「是否可重新赋值」。很多新手在这里容易犯晕,咱们用大白话+代码示例,一次性讲透。
1. 语法格式(新手必记)
Kotlin 很聪明,支持「类型推断」,通常不需要你手动指定变量类型,它会根据你赋的值自动判断。核心语法有两种,优先使用第一种:
kotlin
// 格式1:自动类型推断(推荐,简洁高效)
val/var 变量名 = 值
// 格式2:显式指定类型(当变量先声明后赋值时使用)
val/var 变量名: 数据类型 = 值
2. val:只读引用,不可重新赋值
val(value 的缩写)修饰的变量只能赋值一次,类似 Java 里的 final 变量,核心特点是「引用不可变」。
kotlin
fun main() {
val name: String = "张三"
// name = "李四" // ❌ 报错!Val cannot be reassigned(val 不可重新赋值)
val age = 18 // 类型自动推断为 Int(整数)
// age = 19 // ❌ 报错!
}
3. var:可变变量,可多次赋值
var(variable 的缩写)修饰的变量可以反复修改,核心特点是「引用可变更」,适合变量值需要动态变化的场景。
kotlin
fun main() {
var count = 0
count = 1 // ✅ 正确,可重新赋值
count += 10 // ✅ 正确,现在 count 是 11
var message: String = "Hello"
message = "Hi" // ✅ 正确,可修改值
}
⚠️ 新手必踩坑点 ①:val 不是绝对的"不可变"
这是新手最容易产生误解的地方:val 只保证「变量本身指向的引用不变」,但不保证引用指向的对象内部属性不变。
kotlin
data class User(var name: String, var age: Int)
fun main() {
val user = User("张三", 18)
user.age = 19 // ✅ 完全正确!对象内部的属性 age 是 var,可以修改
// user = User("李四", 20) // ❌ 报错!变量 user 是 val,不能指向新对象
}
避坑原则:优先使用 val,只有明确需要多次改变变量指向时,才用 var。这样能保证代码的稳定性,减少意外修改。
四、基础数据类型与字符串模板
新手只需掌握 4 种常用基础数据类型,就能满足日常 Android 开发需求;而字符串模板是 Kotlin 的"语法糖",能大幅简化字符串拼接,新手必须掌握。
1. 四种常用基础数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
| Int | 整数类型,用于存储年龄、数量等整数 | val age = 20 |
| Double | 浮点数(小数),用于存储分数、金额等 | val price = 99.99 |
| Boolean | 布尔值,只有 true(真)或 false(假),用于判断条件 | val isLogin = false |
| String | 字符串,用双引号括起来,用于存储文本 | val name = "Android" |
重要提醒:Kotlin 中的 String 是不可变的,任何修改字符串的操作(如拼接、转大写)都会返回一个新的字符串对象,不会修改原字符串。
2. 字符串模板:$ 的妙用(新手高频使用)
Java 中用 + 号拼接字符串,既繁琐又容易出错,而 Kotlin 的字符串模板用 $ 符号就能轻松搞定,核心有 3 种用法,全部掌握就能应对日常开发:
kotlin
fun main() {
val name = "小明"
val score = 95.5
// 1. 直接引用变量($ + 变量名)
println("学生姓名:$name")
// 2. 引用表达式(复杂逻辑用花括号 {} 包起来)
println("成绩单:$score 分,等级:${if (score >= 90) "优秀" else "良好"}")
// 3. 打印单纯的 $ 符号,前面加反斜杠 \ 转义
println("这本书的价格是 \$99")
}
运行结果如下,简洁又直观:
plain
学生姓名:小明
成绩单:95.5 分,等级:优秀
这本书的价格是 $99
五、Kotlin 核心重难点:空安全机制(Android 开发必掌握)
空指针异常(NullPointerException,简称 NPE)是 Java 开发中永远的痛,俗称「十亿美元的错误」。而 Kotlin 最伟大的创新,就是在编译期就将绝大部分 NPE 扼杀在摇篮里,这也是 Kotlin 最核心的优势。
Kotlin 空安全的核心理念:默认情况下,所有变量都不能为空。只有明确声明为"可空类型",才能赋值为 null。
1. 可空类型 String? 与不可空类型 String(核心区别)
两者的唯一区别,就是在类型名后面加一个问号 ?,新手一定要分清:
kotlin
fun main() {
// 不可空类型:直接写类型名,绝对不能赋值为 null
var name: String = "张三"
// name = null // ❌ 编译报错!Null can not be a value of a non-null type String
// 可空类型:类型名后面加 ?,允许赋值为 null
var nickname: String? = "阿三"
nickname = null // ✅ 正确!可空类型可以置空
}
关键限制:可空类型的变量,不能直接调用它的方法或属性(如 nullableName.length),否则编译不通过。这是 Kotlin 强制你做空检查的手段,从根源上避免 NPE。
2. 三大空安全操作符(必学必会)
为了优雅地处理可空变量,Kotlin 提供了三个强大的操作符,新手需牢记每种操作符的用法和场景,优先使用前两种。
(1)安全调用符 ?.(最常用,优雅避坑)
语法:可空变量?\.方法/属性
作用:如果对象不为 null,就执行后面的方法/属性;如果为 null,直接返回 null,程序不会崩溃,相当于"有值就执行,没值就算了"。
kotlin
fun main() {
val str: String? = "Kotlin"
println(str?.length) // 输出 6(str 不为 null,正常获取长度)
val nullStr: String? = null
println(nullStr?.length) // 输出 null,程序正常运行,不崩溃
}
(2)Elvis 运算符 ?:(给 null 兜底)
语法:可空变量 ?: 默认值
作用:如果左边的表达式结果不为 null,就返回左边;如果为 null,就返回右边的默认值,常和安全调用符配合使用,是处理 null 的"神器"。
kotlin
fun main() {
val nullableName: String? = null
// 如果 nullableName 为空,就使用 "未命名" 作为默认值
val realName = nullableName ?: "未命名"
println(realName) // 输出:未命名
// 配合 ?. 使用,完美处理链式调用(Android 开发高频场景)
val user: User? = null
val userName = user?.name ?: "默认用户"
println(userName) // 输出:默认用户
}
data class User(val name: String, val age: Int)
(3)非空断言 !!.(慎用,新手劝退符)
语法:可空变量\!\!\.方法/属性
作用:强制告诉编译器:"我确定这玩意儿绝不为空,你别管了!"。后果:如果实际上它是 null,App 会立刻崩溃闪退,抛出 KotlinNullPointerException。
kotlin
fun main() {
val str: String? = null
// 危险操作!!!
val length = str!!.length // 💥 运行时崩溃,App 直接闪退
}
⚠️ 新手必踩坑点 ②:滥用 !! 导致闪退 + 不会看日志
很多新手遇到可空变量编译报错,图省事直接一个 !! 怼上去,结果编译通过了,App 一到线上就疯狂崩溃,还不会排查问题。这里给出正确做法和排查技巧:
kotlin
// 错误示例(新手常犯)
fun printUserName(user: User?) {
// 滥用 !!,如果 user 为 null,会崩溃
println("用户姓名:${user!!.name}")
}
// 正确示例(优先使用 ?. 和 ?:)
fun printUserName(user: User?) {
// 方式1:简洁处理,适合简单场景
println("用户姓名:${user?.name ?: "未命名"}")
// 方式2:先做 null 判断,适合复杂逻辑
if (user != null) {
println("用户姓名:${user.name}")
} else {
println("用户姓名:未命名")
}
}
// 排查技巧:App 闪退后,打开 AS 底部 Logcat 面板,搜索 FATAL EXCEPTION,
// 堆栈信息会精确告诉你哪一行代码因为 !! 断言失败而崩溃,修改为 ?. 或 ?: 即可。
六、综合小案例:用户信息卡打印器(实战练习)
咱们把今天学的变量、函数、空安全全部串起来,写一个实战小案例,巩固所学知识。案例需求清晰,全程无 !!,健壮性拉满,新手可直接复制运行。
案例需求
-
编写函数 printUserCard(name: String?, age: Int, isLogin: Boolean?)
-
name 可能为空,空时显示"未命名";
-
isLogin 可能为空,空时默认按"未登录"处理;
-
完全使用空安全语法,严禁出现 !!;
-
用多行字符串模板打印规范的用户信息卡。
完整代码实现
kotlin
fun main() {
// 测试用例1:全部有值
printUserCard("张三", 25, true)
// 测试用例2:name 和 isLogin 为空
printUserCard(null, 18, null)
// 测试用例3:未登录状态
printUserCard("李四", 30, false)
}
/**
* 用户信息卡打印器函数
* @param name 用户名(可空)
* @param age 年龄(不可空)
* @param isLogin 登录状态(可空)
*/
fun printUserCard(name: String?, age: Int, isLogin: Boolean?) {
// 1. 优雅处理 name 为空的情况 (Elvis 运算符)
val displayName = name ?: "未命名"
// 2. 优雅处理 isLogin 为空的情况,空时视为未登录
val loginStatus = if (isLogin ?: false) "已登录" else "未登录"
// 3. 使用多行字符串模板打印信息卡,trimIndent() 自动对齐
println("""
======= 用户信息卡 =======
姓名:$displayName
年龄:$age
状态:$loginStatus
==========================
""".trimIndent())
}
运行结果
plain
======= 用户信息卡 =======
姓名:张三
年龄:25
状态:已登录
==========================
======= 用户信息卡 =======
姓名:未命名
年龄:18
状态:未登录
==========================
======= 用户信息卡 =======
姓名:李四
年龄:30
状态:未登录
==========================
案例解析
这个案例覆盖了今天所有核心知识点,新手一定要吃透:
-
函数声明:带参数、带注释,规范编写函数,提升代码可读性;
-
空安全处理:用 ?: 给 name 和 isLogin 设置默认值,全程无 !!,避免崩溃;
-
字符串模板:用多行字符串(""" ... """)和 $ 符号,简洁拼接信息;
-
逻辑判断:结合 if-else 处理登录状态,兼顾简洁性和可读性。
七、总结与下篇预告
恭喜你坚持学完了 Kotlin 基础入门的第一课!我们来快速回顾一下今天的核心收获,帮你梳理记忆:
-
✅ 变量声明:优先用 val(只读,引用不可变),非必要不用 var(可变);
-
✅ 基础类型:掌握 Int、Double、Boolean、String 四种常用类型,了解 String 不可变性;
-
✅ 字符串模板:用 $ 符号快速拼接变量和表达式,告别繁琐的 + 号;
-
✅ 空安全灵魂三连:可空类型加 ?、安全调用 ?.、Elvis 兜底 ?:;
-
✅ 避坑指南:val 内部属性可能变、坚决不滥用 !! 断言,学会用 Logcat 排查崩溃。
这些知识是 Android 开发的地基,也是后续学习集合、循环、高阶函数、协程的必备前提。一定要多敲代码、多试错,把基础打牢------编程没有捷径,实操才是王道。
✨ 如果本文对你有帮助,欢迎点赞、收藏,让更多零基础的小伙伴少走弯路!
下篇我们将深入学习 Kotlin 集合、循环与高阶函数,解锁更强大的代码操作能力,不见不散!