Kotlin 类型转换 #
一、类型转换概述 #
Kotlin 是强类型语言,不支持隐式类型转换,需要显式进行类型转换。
1.1 与 Java 的区别 #
java
// Java:隐式转换
int a = 100;
long b = a; // 自动转换
kotlin
// Kotlin:需要显式转换
val a: Int = 100
// val b: Long = a // 编译错误
val b: Long = a.toLong() // 正确
二、数值类型转换 #
2.1 转换函数 #
所有数值类型都提供转换函数:
kotlin
val int = 100
int.toByte()
int.toShort()
int.toInt()
int.toLong()
int.toFloat()
int.toDouble()
int.toChar()
2.2 转换示例 #
kotlin
val a: Int = 100
val b: Long = a.toLong()
val c: Double = b.toDouble()
val d: Float = c.toFloat()
val e: Int = d.toInt()
2.3 精度丢失 #
kotlin
val long: Long = 1000000000000L
val int: Int = long.toInt() // 精度丢失
println(int) // -727379968(溢出)
// 安全转换
val safeInt = long.coerceIn(Int.MIN_VALUE, Int.MAX_VALUE).toInt()
2.4 自动类型提升 #
运算时会自动提升类型:
kotlin
val a: Int = 10
val b: Long = 20L
val sum = a + b // Long
val product = a * b // Long
val c: Float = 1.5f
val d: Double = 2.5
val result = c + d // Double
三、类型检查 #
3.1 is 操作符 #
使用 is 检查类型:
kotlin
val obj: Any = "Hello"
if (obj is String) {
println(obj.length) // 智能转换为 String
}
// 否定形式
if (obj !is String) {
println("Not a String")
}
3.2 when 中的类型检查 #
kotlin
fun process(obj: Any) {
when (obj) {
is Int -> println("Integer: $obj")
is String -> println("String: ${obj.length}")
is List<*> -> println("List: ${obj.size}")
else -> println("Unknown type")
}
}
3.3 类型检查的限制 #
kotlin
// 不能检查泛型参数的具体类型
val list: List<String> = listOf("A", "B")
// 错误:泛型擦除
// if (list is List<String>) { }
// 正确:检查星投影
if (list is List<*>) {
println("It's a List")
}
四、智能类型转换 #
4.1 基本用法 #
Kotlin 编译器会自动进行智能类型转换:
kotlin
val obj: Any = "Hello"
if (obj is String) {
// obj 自动转换为 String 类型
println(obj.uppercase())
println(obj.length)
}
4.2 智能转换的条件 #
kotlin
// val 局部变量
val obj: Any = "Hello"
if (obj is String) {
println(obj.length) // 正确
}
// var 局部变量(编译器无法保证)
var obj2: Any = "Hello"
if (obj2 is String) {
// 可能需要额外检查
println(obj2.length)
}
// 类属性(val 且没有自定义 getter)
class Person(val name: Any) {
fun print() {
if (name is String) {
println(name.length) // 正确
}
}
}
4.3 智能转换场景 #
kotlin
// if 语句
if (obj is String) {
println(obj.length)
}
// when 语句
when (obj) {
is String -> println(obj.length)
is Int -> println(obj * 2)
}
// while 循环
while (obj !is String) {
// ...
}
// 逻辑表达式
if (obj is String && obj.length > 5) {
println(obj.uppercase())
}
// 提前返回
if (obj !is String) return
println(obj.length) // 智能转换
五、类型转换操作符 #
5.1 不安全转换 as #
as 进行不安全转换,失败时抛出异常:
kotlin
val obj: Any = "Hello"
val str: String = obj as String // 成功
val num: Int = obj as Int // ClassCastException
5.2 安全转换 as? #
as? 进行安全转换,失败时返回 null:
kotlin
val obj: Any = "Hello"
val str: String? = obj as? String // "Hello"
val num: Int? = obj as? Int // null
5.3 使用场景 #
kotlin
fun process(obj: Any) {
// 不安全转换
try {
val str = obj as String
println(str.length)
} catch (e: ClassCastException) {
println("Not a String")
}
// 安全转换(推荐)
val str = obj as? String
println(str?.length ?: "Not a String")
}
六、字符串与数值转换 #
6.1 数值转字符串 #
kotlin
val num = 123
num.toString() // "123"
// 格式化
String.format("%d", num) // "123"
String.format("%04d", num) // "0123"
String.format("%x", num) // "7b"(十六进制)
6.2 字符串转数值 #
kotlin
// 基本转换
"123".toInt() // 123
"123".toLong() // 123L
"3.14".toFloat() // 3.14f
"3.14".toDouble() // 3.14
// 进制转换
"FF".toInt(16) // 255
"1010".toInt(2) // 10
// 安全转换
"abc".toIntOrNull() // null
"123".toIntOrNull() // 123
"FF".toIntOrNull(16) // 255
6.3 处理转换异常 #
kotlin
fun safeToInt(str: String): Int {
return str.toIntOrNull() ?: 0
}
// 使用
val num = safeToInt("123")
val invalid = safeToInt("abc") // 0
七、自定义类型转换 #
7.1 定义转换函数 #
kotlin
class Person(val name: String, val age: Int) {
fun toUser(): User {
return User(name, age)
}
}
class User(val name: String, val age: Int)
val person = Person("Kotlin", 10)
val user = person.toUser()
7.2 扩展函数转换 #
kotlin
fun String.toPerson(): Person {
val parts = this.split(",")
return Person(parts[0], parts[1].toInt())
}
val person = "Kotlin,10".toPerson()
7.3 运算符重载转换 #
kotlin
class Dollar(val amount: Double) {
operator fun plus(other: Euro): Dollar {
return Dollar(amount + other.amount * 1.1)
}
}
class Euro(val amount: Double)
val dollar = Dollar(100.0)
val euro = Euro(50.0)
val total = dollar + euro
八、类型别名与转换 #
8.1 类型别名 #
kotlin
typealias UserName = String
typealias UserId = Long
fun process(name: UserName, id: UserId) {
// 编译时类型别名会被替换为原类型
val str: String = name
val long: Long = id
}
8.2 类型别名不创建新类型 #
kotlin
typealias StringList = List<String>
val list1: StringList = listOf("A", "B")
val list2: List<String> = list1 // 完全相同
// 类型检查
println(list1 is List<*>) // true
println(list1 is StringList) // 编译错误
九、泛型类型转换 #
9.1 泛型擦除 #
kotlin
fun <T> process(list: List<T>) {
// 运行时不知道 T 的具体类型
// if (list is List<String>) { } // 编译错误
}
// 使用具体化类型参数
inline fun <reified T> isType(value: Any): Boolean {
return value is T
}
println(isType<String>("Hello")) // true
println(isType<Int>("Hello")) // false
9.2 星投影 #
kotlin
val list: List<*> = listOf("A", "B", "C")
if (list is List<*>) {
println(list.size)
}
十、最佳实践 #
10.1 优先使用智能转换 #
kotlin
// 推荐
if (obj is String) {
println(obj.length)
}
// 不推荐
if (obj is String) {
println((obj as String).length)
}
10.2 使用安全转换 #
kotlin
// 推荐
val str = obj as? String ?: return
// 不推荐
try {
val str = obj as String
} catch (e: ClassCastException) {
// ...
}
10.3 尽早进行类型检查 #
kotlin
fun process(obj: Any) {
if (obj !is String) return
// 后续代码可以安全使用 String 方法
println(obj.length)
println(obj.uppercase())
}
10.4 使用 when 处理多种类型 #
kotlin
fun describe(obj: Any): String = when (obj) {
is String -> "String of length ${obj.length}"
is Int -> "Integer $obj"
is Boolean -> if (obj) "True" else "False"
is List<*> -> "List with ${obj.size} elements"
else -> "Unknown type"
}
十一、总结 #
类型转换要点:
| 操作符/函数 | 用途 | 安全性 |
|---|---|---|
is / !is |
类型检查 | 安全 |
as |
不安全转换 | 可能抛异常 |
as? |
安全转换 | 返回 null |
toXxx() |
数值转换 | 可能溢出 |
toIntOrNull() |
安全数值转换 | 返回 null |
下一步,让我们学习 字符串!
最后更新:2026-03-27