Kotlin 类型映射(Type Mapping)详解
1. 基础类型映射
Kotlin 与 Java 基本类型映射
// Kotlin 使用对象类型,但在编译时会优化为基本类型
val int: Int = 42 // 对应 Java int/Integer
val long: Long = 42L // 对应 Java long/Long
val double: Double = 3.14 // 对应 Java double/Double
val float: Float = 3.14f // 对应 Java float/Float
val boolean: Boolean = true // 对应 Java boolean/Boolean
val char: Char = 'A' // 对应 Java char/Character
val byte: Byte = 1 // 对应 Java byte/Byte
val short: Short = 1 // 对应 Java short/Short
可空类型映射
// Kotlin 的可空类型映射到 Java 的包装类型
val nullableInt: Int? = null // 对应 Java Integer
val nullableLong: Long? = null // 对应 Java Long
val nullableBoolean: Boolean? = null // 对应 Java Boolean
2. 集合类型映射
List 类型映射
// Kotlin List -> Java List/ArrayList
val kotlinList: List<String> = listOf("A", "B", "C")
// 对应 Java: List<String>
// Kotlin MutableList -> Java ArrayList
val mutableList: MutableList<String> = mutableListOf("A", "B", "C")
// 对应 Java: ArrayList<String>
// 与 Java 互操作
val javaList: java.util.List<String> = kotlinList // 隐式转换
val kotlinFromJava: List<String> = javaList // 隐式转换
Set 类型映射
// Kotlin Set -> Java Set/HashSet
val kotlinSet: Set<Int> = setOf(1, 2, 3)
// 对应 Java: Set<Integer>
val mutableSet: MutableSet<Int> = mutableSetOf(1, 2, 3)
// 对应 Java: HashSet<Integer>
Map 类型映射
// Kotlin Map -> Java Map/HashMap
val kotlinMap: Map<String, Int> = mapOf("a" to 1, "b" to 2)
// 对应 Java: Map<String, Integer>
val mutableMap: MutableMap<String, Int> = mutableMapOf("a" to 1)
// 对应 Java: HashMap<String, Integer>
3. 数组类型映射
基本类型数组
// Kotlin 特殊数组类
val intArray: IntArray = intArrayOf(1, 2, 3) // 对应 Java int[]
val longArray: LongArray = longArrayOf(1L, 2L) // 对应 Java long[]
val doubleArray: DoubleArray = doubleArrayOf(1.0, 2.0) // 对应 Java double[]
val booleanArray: BooleanArray = booleanArrayOf(true, false) // 对应 Java boolean[]
val charArray: CharArray = charArrayOf('a', 'b') // 对应 Java char[]
val byteArray: ByteArray = byteArrayOf(1, 2) // 对应 Java byte[]
val shortArray: ShortArray = shortArrayOf(1, 2) // 对应 Java short[]
val floatArray: FloatArray = floatArrayOf(1.0f, 2.0f) // 对应 Java float[]
对象类型数组
// Array<T> 对应 Java T[]
val stringArray: Array<String> = arrayOf("a", "b") // 对应 Java String[]
val nullableArray: Array<String?> = arrayOf("a", null) // 对应 Java String[]
// 创建指定大小的数组
val sizedArray = Array(5) { i -> "Item $i" }
数组转换
// List 转数组
val list = listOf(1, 2, 3)
val array1: Array<Int> = list.toTypedArray()
val intArray2: IntArray = list.toIntArray()
// 数组转 List
val array = arrayOf(1, 2, 3)
val listFromArray: List<Int> = array.toList()
4. 平台类型映射
Java 互操作中的平台类型
// Java 代码
public class JavaExample {
public String getName() { return "John"; } // @Nullable String
public @NotNull String getTitle() { return "Mr."; }
public List<String> getItems() { return Arrays.asList("a", "b"); }
}
// Kotlin 中使用
val example = JavaExample()
val name: String? = example.name // 可空,因为Java方法可能返回null
val title: String = example.title // 非空,因为@NotNull注解
val items: List<String> = example.items // 平台类型 List<String>!
平台类型注解
// 使用注解明确平台类型
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
// Kotlin 调用时
fun processJavaType(@Nullable nullableStr: String?) {
// 明确处理可空性
}
fun processJavaType(@NotNull notNullStr: String) {
// 可以安全调用
}
5. 函数类型映射
Kotlin 函数类型到 Java 接口
// Kotlin 函数类型
val kotlinFunction: (Int, String) -> Boolean = { i, s -> i > 0 && s.isNotEmpty() }
// 对应 Java 接口
// 实际上映射到 Function2<Integer, String, Boolean>
与 Java 函数式接口互操作
// Java 函数式接口
@FunctionalInterface
interface JavaProcessor {
String process(String input);
}
// Kotlin 中使用
fun useJavaProcessor(processor: JavaProcessor) {
val result = processor.process("test")
}
// 传递 lambda
useJavaProcessor { input -> input.uppercase() }
// SAM 转换
val processor = JavaProcessor { it.uppercase() }
6. 泛型类型映射
型变映射
// Java 通配符 ? extends T 和 ? super T
// Java: List<? extends Number> numbers
// Kotlin 中等价表示
val numbers: List<out Number> = listOf(1, 2.5, 3L) // 协变
val consumer: MutableList<in String> = mutableListOf() // 逆变
// 星投影
val list: List<*> = listOf("a", 1, true) // 对应 Java List<?>
泛型擦除与具体化
// 普通泛型函数(类型擦除)
fun <T> checkType(obj: T): Boolean {
return obj is String // 警告:类型擦除
}
// 内联函数的具体化类型参数
inline fun <reified T> checkTypeReified(obj: Any): Boolean {
return obj is T // 可以正常工作
}
// 使用
val result1 = checkTypeReified<String>("test") // true
val result2 = checkTypeReified<Int>("test") // false
7. 集合与数组性能对比
// 性能测试示例
fun performanceComparison() {
val size = 1_000_000
// IntArray (基本类型数组) - 最高效
val intArray = IntArray(size) { it }
// Array<Int> (包装类型数组) - 次之
val array = Array(size) { it }
// List<Int> - 再次之
val list = List(size) { it }
// MutableList<Int> - 最慢
val mutableList = MutableList(size) { it }
}
8. 自定义类型映射
使用类型别名
// 为复杂类型创建别名
typealias UserId = String
typealias UserMap = Map<UserId, User>
typealias Callback = (Result) -> Unit
// 使用
fun processUser(users: UserMap, callback: Callback) {
// ...
}
自定义值类(内联类)
// 创建类型安全的值类(无运行时开销)
@JvmInline
value class Email(val value: String)
@JvmInline
value class UserId(val value: Long)
// 使用
fun sendEmail(to: Email) {
// 编译时类型安全,运行时无额外开销
}
// 不会混淆不同类型
val email = Email("test@example.com")
val userId = UserId(123L)
// sendEmail(userId) // 编译错误:类型不匹配
9. 与 Java 集合的互操作
转换方法
// Java 集合转 Kotlin 集合
val javaList: java.util.ArrayList<String> = java.util.ArrayList()
val kotlinList: List<String> = javaList.toList()
val mutableKotlinList: MutableList<String> = javaList.toMutableList()
// Kotlin 集合转 Java 集合
val kotlinMutableList = mutableListOf("a", "b")
val javaList2: java.util.List<String> = kotlinMutableList // 直接赋值
val javaArrayList: java.util.ArrayList<String> = ArrayList(kotlinMutableList)
平台集合的注意事项
// Java 方法返回的可变集合
fun getJavaMutableList(): java.util.List<String> {
return java.util.ArrayList(listOf("a", "b"))
}
// 在 Kotlin 中使用
val list = getJavaMutableList()
list.add("c") // 可以,但可能破坏不可变性假设
// 更好的做法:防御性拷贝
val safeList = getJavaMutableList().toList() // 创建不可变副本
10. 实际应用示例
示例1:处理混合类型数据
fun processMixedData(data: Any) {
when (data) {
is Int -> println("整数: $data")
is String -> println("字符串: ${data.length}")
is IntArray -> println("整数数组: ${data.sum()}")
is List<*> -> println("列表大小: ${data.size}")
else -> println("未知类型")
}
}
示例2:类型安全的 API 设计
// 使用值类创建类型安全的API
@JvmInline value class Meter(val value: Double)
@JvmInline value class Kilometer(val value: Double)
fun Meter.toKilometer(): Kilometer = Kilometer(value / 1000)
fun Kilometer.toMeter(): Meter = Meter(value * 1000)
// 使用 - 类型安全
val distanceInMeters = Meter(1000.0)
val distanceInKm = distanceInMeters.toKilometer()
// val error = distanceInMeters + distanceInKm // 编译错误
示例3:处理 JSON 映射
// 使用类型映射处理 JSON
data class User(
val id: Long,
val name: String,
val email: String,
val tags: List<String>
)
fun parseUser(json: String): User {
// 假设使用 Gson 或 Jackson
val map = mapOf<String, Any>(
"id" to 123L,
"name" to "John",
"email" to "john@example.com",
"tags" to listOf("admin", "user")
)
return User(
id = map["id"] as Long,
name = map["name"] as String,
email = map["email"] as String,
tags = map["tags"] as List<String>
)
}
最佳实践
- 优先使用 Kotlin 集合:除非需要与 Java 代码深度互操作
- 明确处理可空性:与 Java 互操作时使用适当的注解
- 使用值类:创建类型安全的领域模型
- 注意平台类型:避免在 Kotlin 中传播平台类型
- 性能考虑:大数据集使用基本类型数组
- 类型安全:利用 Kotlin 的类型系统防止运行时错误
Kotlin 的类型映射系统在保证类型安全的同时,提供了与 Java 无缝互操作的能力。合理利用这些特性可以编写更安全、更高效的代码。