前言
在Android开发领域,Kotlin凭借其简洁性和安全性已成为官方推荐语言。本文将通过Kotlin的五大基础语法特性,结合实际应用场景展示它们在Android开发中的独特价值。
一、变量声明:val与var
1.1 不可变优先原则
Kotlin的val
关键字用于声明不可变变量(相当于Java的final):
val PI = 3.14159
val context: Context = requireContext()
最佳实践:
• 在View绑定中优先使用val
val binding: MainBinding by viewBinding()
• 数据类属性推荐使用val
保证线程安全
data class User(val id: Long, val name: String)
1.2 可变变量的使用
var
用于需要修改的变量,在Android开发中常见于:
var currentState = State.LOADING // 页面状态管理
var lastClickTime = 0L // 防重复点击计时
生命周期注意点:
• Fragment/Activity中的var
变量需要在onSaveInstanceState
中保存状态
• ViewModel中的在Fragment/Activity中用到的可变状态建议使用LiveData或StateFlow包装,因为它们可以感知生命周期
二、类型推断和类型转换
2.1 智能类型推断
Kotlin编译器能自动推断大部分变量类型:
val appName = "MyApp" // String
val versionCode = 42 // Int
val dpValue = 16f // Float
2.2 显式类型声明的场景
以下情况需要显式声明类型:
// 可空类型初始化
val cacheDir: File? = getExternalCacheDir()
// 接口类型声明
val callback: OnClickListener = View.OnClickListener { ... }
// 复杂泛型类型
val configMap: Map<String, Pair<Int, Boolean>> = mapOf(...)
示例 : Android资源获取:
val colorRes = when (isDarkTheme) {
true -> R.color.dark_text
false -> R.color.light_text
}
val textColor = ContextCompat.getColor(context, colorRes)
2.3 智能类型转换
自动处理显式转换,减少冗余代码。
Kotlin编译器在类型检查(is
)后自动将对象转换为目标类型,无需显式强制转换。
编译器会生成类似 Java 的 instanceof 检查和强制转换的字节码。
fun printLength(obj: Any) {
if (obj is String) {
// 此处obj自动转换为String类型
println(obj.length)
} else {
println("Not a String")
}
}
🔸kotlin中,智能转换和Java的显式强制转换,哪个性能更好 ?
在 Kotlin 的智能转换(Smart Cast)和 Java 的显式强制转换之间,性能几乎没有区别,因为两者的底层实现最终都依赖 JVM 的类型检查和强制转换机制。
无论是 Kotlin 还是 Java,JVM 都会执行一次 instanceof 检查和一次强制转换。
三、函数设计
3.1 基础函数结构
Kotlin 里函数使用 fun
关键字来定义函数
fun createIntent(context: Context, clazz: Class<*>): Intent {
return Intent(context, clazz).apply {
putExtra(KEY_VERSION, BuildConfig.VERSION_CODE)
}
}
3.2 默认参数与命名参数
默认参数指的是在函数定义时为参数设定默认值。调用函数时,若未为这些参数传值,就会使用默认值。通过参数名: 参数类型 = 默认值
的形式来设置默认参数。
fun greet(name: Strin="Heiko", message: String) {
println("$message, $name!")
}
命名参数允许你通过参数名来指定参数值,而非单纯依靠参数的位置。在调用函数时,使用参数名 = 参数值
的形式指定参数。
fun main() {
// 使用命名参数调用函数
greet(message = "Hello")
}
示例 : 重构传统Builder模式:
fun showDialog(
title: String = "提示",
message: String = "",
confirmText: String = "确定",
cancelable: Boolean = true
) {
// Dialog初始化逻辑
}
// 使用示例
showDialog(
message = "是否保存修改?",
confirmText = "保存"
)
四、字符串模板
4.1 基础插值
val apiUrl = "${BuildConfig.BASE_URL}/api/v${BuildConfig.API_VERSION}"
4.2 复杂表达式处理
fun formatLog(tag: String, vararg params: Any): String {
return "[${System.currentTimeMillis()}] $tag - ${params.joinToString()}".trimIndent()
}
4.3 多行字符串处理
使用"""
val sqlQuery = """
SELECT * FROM ${UserTable.TABLE_NAME}
WHERE ${UserTable.COLUMN_AGE} > ?
AND ${UserTable.COLUMN_STATUS} = 'ACTIVE'
ORDER BY ${UserTable.COLUMN_CREATED_AT} DESC
""".trimIndent()
五、空安全机制的使用
Kotlin 明确区分可空类型和非空类型。在类型后面加上 ?
表示该类型的变量可以为 null
,不加则表示变量不能为 null
。
// 非空类型,不能赋值为 null
var nonNullString: String = "Hello"
// 可空类型,可以赋值为 null
var nullableString: String? = null
5.1 空安全操作符
- 安全调用操作符(
?.
): 在变量可能为 null 的情况下安全地调用其方法或访问其属性,避免空指针异常 - Elvis 操作符(
?:
): 用于在变量为null
时提供一个默认值。 - 非空断言操作符(
!!
): 用于明确告诉编译器该变量不为null
。若变量实际上为null
,会抛出空指针异常。 - 安全类型转换操作符(
as?
): 用于安全地进行类型转换。若转换失败,结果为null
,不会抛出类型转换异常。 - 集合的空安全处理 (
filterNotNull()
) : 对于可能包含null
元素的集合,可以使用filterNotNull()
函数过滤掉null
元素。
fun main() {
// 安全调用操作符(?.)
var nullableString: String? = null
val length = nullableString?.length
println("nullableString 的长度: $length")
// Elvis 操作符(?:)
val result = nullableString ?: "default"
println("使用 Elvis 操作符的结果: $result")
// 非空断言操作符(!!)
try {
val forceLength = nullableString!!.length
println("使用非空断言操作符得到的长度: $forceLength")
} catch (e: NullPointerException) {
println("发生空指针异常: ${e.message}")
}
// 安全类型转换操作符(as?)
val animal: Animal = Dog()
val dog: Dog? = animal as? Dog
// 安全调用操作符(?.)
dog?.bark()
// 集合的空安全处理 (filterNotNull())
val nullableList: List<String?> = listOf("apple", null, "banana", null, "cherry")
val nonNullList = nullableList.filterNotNull()
println("过滤掉 null 后的列表: $nonNullList")
}
open class Animal
class Dog : Animal() {
fun bark() {
println("Woof!")
}
}
5.2 改进与Java的互操作性
在 Kotlin 调用 Java 代码时,可借助 @Nullable
和 @NotNull
注解帮助 Kotlin 编译器理解 Java 代码中的空安全情况。
- 使用 @Nullable : Kotlin会当非空类型处理
- 使用 @NonNull : Kotlin会当空类型处理
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaClass {
@NotNull
public String getNonNullString() {
return "This is a non-null string";
}
@Nullable
public String getNullableString() {
return Math.random() > 0.5 ? "A string" : null;
}
}
val javaClass = JavaClass()
// Kotlin 编译器根据 @NotNull 注解知道返回值不为 null
val nonNullString: String = javaClass.getNonNullString()
// Kotlin 编译器根据 @Nullable 注解知道返回值可能为 null
val nullableString: String? = javaClass.getNullableString()
在 Android中,@Nullable 和 @NotNull 注解有多个不同的来源包
- org.jetbrains:annotations : @NotNull和@Nullable
- androidx.annotation : @NonNull和@Nullable