3. 基本数据类型转换

基本数据类型转换 学习卡片

任务说明

本案例实现 Kotlin 中 Int、Double、String 等基本数据类型之间的安全转换,重点处理转换过程中可能出现的 NumberFormatException 等异常。最终提供一个可复用的转换工具函数及对应的验证调用。

核心实现

// TypeConverter.kt
import kotlin.math.roundToInt

object TypeConverter {

    // String → Int,失败返回 null
    fun String.toIntOrNullSafe(): Int? =
        this.trim().toIntOrNull()

    // String → Double,失败返回 null
    fun String.toDoubleOrNullSafe(): Double? =
        this.trim().toDoubleOrNull()

    // Double → Int(四舍五入),溢出时返回 null
    fun Double.toIntSafe(): Int? {
        if (this.isNaN() || this.isInfinite()) return null
        if (this > Int.MAX_VALUE.toDouble() || this < Int.MIN_VALUE.toDouble()) return null
        return this.roundToInt()
    }

    // Int → Double(始终安全)
    fun Int.toDoubleSafe(): Double = this.toDouble()

    // String → Int,带默认值
    fun String.toIntOrDefault(default: Int): Int =
        this.toIntOrNullSafe() ?: default

    // String → Double,带默认值
    fun String.toDoubleOrDefault(default: Double): Double =
        this.toDoubleOrNullSafe() ?: default

    // 通用安全转换:String → 指定数值类型
    inline fun <reified T : Number> String.toNumberOrNull(): T? = when (T::class) {
        Int::class -> this.toIntOrNullSafe() as? T
        Double::class -> this.toDoubleOrNullSafe() as? T
        Long::class -> this.trim().toLongOrNull() as? T
        Float::class -> this.trim().toFloatOrNull() as? T
        else -> null
    }
}

fun main() {
    // 验证用例
    val validInt = "42"
    val invalidInt = "12abc"
    val validDouble = "3.14"
    val invalidDouble = "3.14.15"
    val largeDouble = 1e10
    val normalDouble = 2.7

    println("'$validInt'.toIntOrNullSafe() = ${TypeConverter.run { validInt.toIntOrNullSafe() }}")
    println("'$invalidInt'.toIntOrNullSafe() = ${TypeConverter.run { invalidInt.toIntOrNullSafe() }}")
    println("'$validDouble'.toDoubleOrNullSafe() = ${TypeConverter.run { validDouble.toDoubleOrNullSafe() }}")
    println("'$invalidDouble'.toDoubleOrNullSafe() = ${TypeConverter.run { invalidDouble.toDoubleOrNullSafe() }}")
    println("$largeDouble.toIntSafe() = ${TypeConverter.run { largeDouble.toIntSafe() }}")
    println("$normalDouble.toIntSafe() = ${TypeConverter.run { normalDouble.toIntSafe() }}")
    println("'$invalidInt'.toIntOrDefault(-1) = ${TypeConverter.run { invalidInt.toIntOrDefault(-1) }}")
    println("'$validInt'.toNumberOrNull<Int>() = ${TypeConverter.run { validInt.toNumberOrNull<Int>() }}")
    println("'$validDouble'.toNumberOrNull<Double>() = ${TypeConverter.run { validDouble.toNumberOrNull<Double>() }}")
}

关键设计说明

  • 安全转换:所有可能失败的转换均返回 null 而非抛出异常,调用方需处理空值。
  • Double→Int 溢出保护:先检查 NaN、无穷大及超出 Int 范围的情况,再执行四舍五入。
  • 泛型扩展:toNumberOrNull 支持 Int、Double、Long、Float 四种类型,通过 reified 实现类型分发。
  • 默认值重载:提供带默认值的版本,便于在配置解析等场景直接使用。

编译与运行

# 保存为 TypeConverter.kt,然后执行:
kotlinc TypeConverter.kt -include-runtime -d converter.jar
java -jar converter.jar

验证方法与判定标准

运行 main() 后,观察输出是否符合以下预期(这些结果由代码逻辑直接推出):

  • '42'.toIntOrNullSafe() = 42
  • '12abc'.toIntOrNullSafe() = null
  • '3.14'.toDoubleOrNullSafe() = 3.14
  • '3.14.15'.toDoubleOrNullSafe() = null
  • 1.0E10.toIntSafe() = null(超出 Int 范围)
  • 2.7.toIntSafe() = 3(四舍五入)
  • '12abc'.toIntOrDefault(-1) = -1
  • '42'.toNumberOrNull<Int>() = 42
  • '3.14'.toNumberOrNull<Double>() = 3.14

若输出与上述一致,说明类型转换及异常处理逻辑正确;若出现 NumberFormatException 或非预期 null,则需检查对应转换分支。

类型转换安全处理流程 输入 String / Double / Int 转换类型 String→Int / String→Double Double→Int / Int→Double 异常检查 NumberFormatException 溢出 / NaN / Inf 结果 值 / null 分支处理策略 • 成功路径:返回转换后的数值 • 失败路径:返回 null(不抛出异常) • 带默认值版本:失败时返回调用方指定的默认值 示例输入 "42" → Int 42 "12abc" → null 2.7 → 3 (四舍五入) 验证观测点 1. 非法字符串(如 "12abc")转换后返回 null,而非抛出异常 2. 超出 Int 范围的 Double(如 1e10)转换后返回 null 3. 正常数值(如 "42"、3.14)转换结果与预期一致 4. 带默认值版本在失败时返回默认值