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() = null1.0E10.toIntSafe() = null(超出 Int 范围)2.7.toIntSafe() = 3(四舍五入)'12abc'.toIntOrDefault(-1) = -1'42'.toNumberOrNull<Int>() = 42'3.14'.toNumberOrNull<Double>() = 3.14
若输出与上述一致,说明类型转换及异常处理逻辑正确;若出现 NumberFormatException 或非预期 null,则需检查对应转换分支。