Kotlin: Kotlin变量与类型系统深入解析

最后更新:2026-08-26

Kotlin 的类型系统不是 Java 的翻版——它用智能转换消灭强制转型,用 // 构建完整的类型代数,让类型系统为你工作而非与你对抗。

1. 你将学到


2. 一个开发者的真实故事

(1) 痛点:Java 类型转换地狱

Bob 在维护 OrderProcessor 的 Java 代码时,到处是强制类型转换:、。一次漏写 instanceof 检查就导致 ClassCastException,生产环境每季度 3-5 次。

(2) Kotlin 智能转换的解法

KOTLIN
// Java: verbose and error-prone
if (obj instanceof Order) {
    Order order = (Order) obj;  // Must cast again
    System.out.println(order.getId());
}

// Kotlin: smart cast eliminates the cast
if (obj is Order) {
    println(obj.id)  // No cast needed!
}

Kotlin 编译器在 检查后自动插入安全转换,Bob 再也没写过一行强制转型代码。


3. 基本类型

(1) 数值类型

Kotlin 没有暴露 Java 的原始类型(/),一切皆为对象,但编译器在 JVM 上优化为原始类型。

KOTLIN
val intValue: Int = 42          // 32-bit
val longValue: Long = 42L       // 64-bit
val doubleValue: Double = 3.14  // 64-bit IEEE 754
val floatValue: Float = 3.14f   // 32-bit IEEE 754

// Underscore for readability
val million = 1_000_000
val creditCard = 1234_5678_9012_3456L
val bytes = 0b11010010_01101001
类型 位数 范围 对应 Java
8 -128 ~ 127
16 -32768 ~ 32767
32 -2³¹ ~ 2³¹-1
64 -2⁶³ ~ 2⁶³-1
32 IEEE 754
64 IEEE 754

(2) 非数值类型

KOTLIN
val bool: Boolean = true
val char: Char = 'A'
val str: String = "OrderProcessor"

// Character is NOT a number in Kotlin
// val code: Int = 'A'  // ERROR
val code: Int = 'A'.code  // OK: 65
val charFromCode: Char = 65.toChar()  // OK: 'A'

4. 智能转换(Smart Cast)

Kotlin 编译器在类型检查后自动将变量转换为更具体的类型,无需手动转型。

(1) 基本智能转换

KOTLIN
fun process(input: Any) {
    // After 'is' check, compiler smart casts
    if (input is String) {
        println(input.length)  // Smart cast to String
    }

    // After '!is' check
    if (input !is String) return
    println(input.length)  // Smart cast to String
}

// Smart cast with when
fun describe(obj: Any): String = when (obj) {
    is String -> "String: ${obj.length} chars"     // Smart cast
    is Int -> "Int: ${obj.dec()}"                   // Smart cast
    is List<*> -> "List: ${obj.size} items"         // Smart cast
    else -> "Unknown"
}

(2) 智能转换的限制

KOTLIN
// WARNING: smart cast may not work with var or custom getters
var obj: Any = "Hello"
if (obj is String) {
    // obj could be changed between check and use
    // println(obj.length)  // WARNING in some cases
}

// Safe approach: use local val
val safeObj = obj
if (safeObj is String) {
    println(safeObj.length)  // OK - guaranteed stable
}

(3) Java cast vs Kotlin smart cast

维度 Java Kotlin
语法 自动
安全 运行时可能 CCE 编译期保证
代码量 检查 + 转型两步 检查即转型一步
空安全 可能 NPE 自动处理可空

5. 显式类型转换

Kotlin 不支持隐式窄化转换(如 → ),所有转换必须显式调用。

(1) 转换函数

KOTLIN
val longVal: Long = 42L
val intVal: Int = longVal.toInt()    // Explicit narrowing
val doubleVal: Double = 3.99
val intFromDouble: Int = doubleVal.toInt()  // Truncates: 3

// String to number
val parsed: Int = "42".toInt()
val parsedDouble: Double = "3.14".toDouble()

// Number to string
val strVal: String = 42.toString()

(2) 为什么没有隐式转换?

KOTLIN
// This would silently lose data - Kotlin prevents it
val longValue: Long = 2_147_483_648L  // Exceeds Int.MAX_VALUE
// val intValue: Int = longValue  // COMPILE ERROR

// Must be explicit about potential data loss
val intValue: Int = longValue.toInt()  // OK but may overflow
转换类型 Java Kotlin
宽化(Int→Long) 隐式 显式
窄化(Long→Int) 隐式(有风险) 显式
字符串→数字
数字→字符串

6. 三大顶层类型

(1) 类型层次图

100%
classDiagram
    Any --> String
    Any --> Int
    Any --> Order
    Any --> Unit
    Any --> Nothing
    class Any {
        +equals()
        +hashCode()
        +toString()
    }
    class Unit {
        <<singleton>>
    }
    class Nothing {
        <<never returns>>
    }

(2) Any:所有非空类型的父类

KOTLIN
// Any is the root of the Kotlin type hierarchy (like Object in Java)
val obj: Any = "Hello"
val obj2: Any = 42
val obj3: Any = Order("ORD-001", 299.99, "CONFIRMED")

// Any has only 3 methods: equals, hashCode, toString
// Use Any? for nullable root type

(3) Unit:函数的"无返回值"

KOTLIN
// Unit is like void in Java, but it's a real type
fun logOrder(order: Order): Unit {  // Unit return is optional
    println("Processing ${order.id}")
}

fun logOrder2(order: Order) {  // Equivalent - Unit inferred
    println("Processing ${order.id}")
}

// Unit is a singleton - can be used as a value
val unitValue: Unit = Unit

(4) Nothing:永远不会到达

KOTLIN
// Nothing means "this code never returns"
fun fail(message: String): Nothing {
    throw IllegalStateException(message)
}

// Useful for Elvis operator with exceptions
val customer = order.customer ?: fail("Customer required")

// Infinite loop also returns Nothing
fun infiniteLoop(): Nothing {
    while (true) { /* never returns */ }
}

(5) 三大顶层类型对比

类型 含义 使用场景 Java 对应
所有非空类型的父类 通用引用
函数无有意义返回值 副作用函数
永远不会到达 异常抛出/死循环 无对应

7. 类型别名(typealias)

KOTLIN
// Simplify complex type signatures
typealias OrderMap = Map<String, List`<Order>`>
typealias OrderProcessor = (List`<Order>`) -> List`<String>`
typealias USD = Double

// Usage
val ordersByCustomer: OrderMap = mapOf(
    "Alice" to listOf(Order("ORD-001", 299.99, "CONFIRMED"))
)

typealias Predicate`<T>` = (T) -> Boolean
val isHighValue: Predicate`<Order>` = { it.total > 10_000 }

// typealias does NOT create new types - just aliases
val map: OrderMap = ordersByCustomer  // Same type

8. 完整示例:OrderProcessor 类型安全处理

KOTLIN
// ============================================
// OrderProcessor - Type-Safe Event Processing
// Feature: Process order events with smart cast
// ============================================

typealias OrderId = String
typealias USD = Double

sealed class OrderEvent {
    data class Created(val orderId: OrderId, val total: USD) : OrderEvent()
    data class Paid(val orderId: OrderId, val amount: USD) : OrderEvent()
    data class Shipped(val orderId: OrderId, val trackingCode: String) : OrderEvent()
    data class Cancelled(val orderId: OrderId, val reason: String) : OrderEvent()
}

fun handleEvent(event: OrderEvent): String = when (event) {
    is OrderEvent.Created -> {
        // Smart cast: event.orderId and event.total available
        val threshold = 10_000
        val priority = if (event.total > threshold) "VIP" else "STANDARD"
        "Order ${event.orderId} created (\$${event.total} USD) -> $priority"
    }
    is OrderEvent.Paid -> {
        val tax = event.amount * 0.08
        "Order ${event.orderId} paid: \$${event.amount} USD (tax: \$$tax USD)"
    }
    is OrderEvent.Shipped ->
        "Order ${event.orderId} shipped: ${event.trackingCode}"
    is OrderEvent.Cancelled ->
        "Order ${event.orderId} cancelled: ${event.reason}"
}

fun main() {
    val events: List`<OrderEvent>` = listOf(
        OrderEvent.Created("ORD-001", 299.99),
        OrderEvent.Created("ORD-002", 15_000.00),
        OrderEvent.Paid("ORD-001", 299.99),
        OrderEvent.Shipped("ORD-001", "TRK-ABC123"),
        OrderEvent.Cancelled("ORD-003", "Customer request")
    )

    events.forEach { event ->
        val result = handleEvent(event)
        println(result)
    }

    // Type check with smart cast
    val anyEvent: Any = events[0]
    if (anyEvent is OrderEvent.Created) {
        println("\nSmart cast works: ${anyEvent.orderId} costs \$${anyEvent.total} USD")
    }
}

输出:

TEXT 📖 仅展示
Order ORD-001 created ($299.99 USD) -> STANDARD
Order ORD-002 created ($15000.0 USD) -> VIP
Order ORD-001 paid: $299.99 USD (tax: $23.999200000000002 USD)
Order ORD-001 shipped: TRK-ABC123
Order ORD-003 cancelled: Customer request

Smart cast works: ORD-001 costs $299.99 USD

❓ 常见问题

Q Kotlin 的 Int 和 Java 的 int 是同一个东西吗?
A 在 JVM 上,Kotlin 的 Int 编译为 Java 的 int(原始类型),当需要对象时自动装箱为 Integer。开发者无需关心这个差异。
Q 智能转换什么时候不生效?
A 当变量是 且可能被并发修改,或有自定义 getter 时,编译器无法保证检查和使用的类型一致,智能转换不生效。
Q Nothing 类型有什么实际用途?
A 主要用于标记"永远不会返回"的函数(如抛异常),让编译器理解后续代码不可达,从而允许智能转换和 Elvis 运算符中使用。
Q typealias 会创建新类型吗?
A 不会。typealias 只是类型别名,编译器会替换为原始类型。需要真正的类型安全包装请用 inline class / value class。
Q 为什么 Kotlin 不支持隐式类型转换?
A 因为隐式窄化转换(如 Long→Int)会静默丢失数据,是 Bug 的常见来源。显式转换让开发者明确知道可能的数据丢失。
Q Any 和 Any? 有什么区别?
A Any 是所有非空类型的父类,Any? 是所有类型(包括可空)的父类。Any? = Any | null,是 Kotlin 类型系统的真正顶层。

📖 小节


📝 作业

  1. 基础题(难度⭐):声明不同类型的变量(Int、Double、Boolean、String),打印它们的类型 。提示:使用
  2. 进阶题(难度⭐⭐):写一个函数接收 ,用智能转换处理 String(打印长度)和 Int(打印平方值)。提示:
  3. 挑战题(难度⭐⭐⭐):用 和密封类设计一个订单事件类型系统,用 穷尽处理所有事件类型。提示:参考第 8 节完整示例

← 上一课 | 下一课 →

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏