【Kotlin系统化精讲:肆】 | 数据类型之基本数据类型:代码世界里的砖瓦水泥沙

前言

你以为KotlinInt就是Javaint?🧐 大错特错!这里的数字会呼吸,字符能跳舞,连布尔值都藏着反常规操作。作为构建代码宇宙的原子粒子,基本类型远不只是存储工具------它们自带Kotlin式哲学。好比拼乐高时突然发现积木块能自动变形,这场​"筑基之旅"​将颠覆你对数据容器的认知。

本章节将带你拆箱这些看似简单实则暗藏玄机的​"代码食材"

千曲 而后晓声,观千剑 而后识器。虐它千百遍 方能通晓其真意


数值类型:二进制世界的精密天平 ⚖️

整型四骑士:内存与数值的博弈

类型 内存空间 取值范围 字面值规则
Byte 8-bit -2⁷ ~ 2⁷ - 1 (-128 ~ 127) 直接写数字: val status = 127
Short 16-bit -2¹⁵ ~ 2¹⁵ - 1 (-32768 ~ 32767) 罕见直接声明 ,常由Int自动推导降级
Int 32-bit -2³¹ ~ 2³¹ - 1 (-2147483648 ~ 2147483647) 21亿 默认整型 ​: val age = 30
Long 64-bit -2⁶³ ~ 2⁶³ - 1 (-9.2e18 ~ 9.2e18) 后缀L标识: val star = 999999999999L

🔥 ​颠覆认知的特性​:

kotlin 复制代码
val money = 1_000_000   // 下划线是视觉分隔符(编译时自动忽略)  
val MAX_INT = Int.MAX_VALUE + 1  // 溢出!实际值=2147483647(最大值)

⚠️ ​危险操作 ​:3000000000超过Int最大值,必须写作3_000_000_000L


浮点型:精度与范围的钢丝舞

类型 内存空间 精度 典型误区
Float 32-bit 6~7位有效数字 字面值需加F/fval π = 3.14F
Double 64-bit 15~16位有效数字 默认浮点型 ​: val speed = 299792458.0

💣 ​精度地雷现场​:

kotlin 复制代码
fun main() {  
    val productA = 0.1f * 20  
    val productB = 0.1.toFloat() * 20 // 显式转换更安全  
    println(productA) // 输出:2.0 ✅  
    println(0.1f * 0.2f) // 输出:0.020000001 ❌ 误差爆炸!  
}  

👉 ​黄金法则 ​:金钱计算必须用BigDecimal("0.1"),禁止用浮点型!


类型转换:绝对禁区 🚫

Java的隐式转换在Kotlin中是编译级错误​!

kotlin 复制代码
val count: Int = 100  
val number: Long = count // ❌ 编译报错!禁止自动转Long  

✅ ​正确转换姿势​(三连招):

Kotlin 复制代码
    // 1、显式变形术
    val 城市人口 = 员工数.toLong() // Int ➡️ Long  
    val 体重 = 70.5.toInt()      // Double ➡️ Int (小数点被截断!) 
    
    // 2、类型安全操作符
    val 距离 = "42.195".toDoubleOrNull() ?: 0.0 // 防转换崩溃
    
    // 3、智能上下文转型
    fun calculate(price: Double) { /*...*/ }  
    calculate(100.toDouble()) // Int手动升格为Double

⛔ ​死亡陷阱案例​:

ini 复制代码
val sale = 9_000_000_000 // 编译器默认Int → 溢出!  
val realSale = 9_000_000_000L // ✅ 正确写法  

val percent = 80 / 100      // 整数除法 → 输出0!  
val realPercent = 80.0 / 100 // ✅ Double除法 → 输出0.8  

🔄 转换安全三原则​:

graph TD A[小类型变量] -->|严禁直接赋值| B[大类型变量] B --> C[必须调用.toXXX强制转换]

布尔类型:非黑即白的阴谋家 🕶️

Boolean绝非简单的true/false开关,而是掌控代码生死的决策暴君。它用绝对的二元统治,在条件、循环、断言中掀起腥风血雨------但暗藏玄机!

布尔本质:非此即彼的暴政

kotlin 复制代码
val 手机欠费 = true
val 有网络信号 = false

👉 ​核心铁律​:

  • 禁止用01替代布尔值(编译级封杀!)。
  • 任何类型都不能自动转为Booleanif(1){...}直接报错)。
  • 必须显式比较 产生布尔结果:if(存款 > 0)

⚠️ ​颠覆Java的三观​:

kotlin 复制代码
// Java允许的骚操作:用null当false  
Boolean javaFlag = null;  
if (javaFlag) { /* 不会执行 */ }  

// Kotlin死亡陷阱:  
val kotlinFlag: Boolean? = null  
if (kotlinFlag) { /* 编译核爆 💥 !必须显式判空 */ }  

布尔黑科技:智能类型斩首术

Boolean遇上is检测,触发编译器暴力变身:

kotlin 复制代码
fun 支付验证(凭证: Any) {
    // 传统Java写法:
    if (凭证 is String) {
        val 文本凭证 =凭证 as String // 强制转型+重复判断
        println(文本凭证.length)
    }

    // Kotlin处决方案:
    if (凭证 is String) {
        println(凭证.length) // 凭证被自动斩首→String类型!
    }
}

👉 原理is检测产生Boolean的同时,编译器在作用域内就地执行类型转换​!

场景 传统写法 智能转换写法
判空后调用 if(obj!=null){obj.foo()} if(obj!=null){obj.foo()} (相同但有编译优化)
类型检测 if(obj is Dog){(obj as Dog).bark()} if(obj is Dog){obj.bark()}
区间检查 if(i in 1..10){i.toFloat()} if(i in 1f..10f){i/2}i自动升格为Float

布尔操作符:决策核按钮💣

操作符 含义 死亡陷阱案例
&& 逻辑与 网络连通 && 服务器响应
` `
! 逻辑非 if(!文件已锁定){编辑内容}
xor 异或(新武器) true xor true = false 男生 xor 女生 = 可以谈恋爱

⚠️ ​短路执行核危机​:

kotlin 复制代码
val 核按钮按下 = true  
val 自毁程序 = { println("地球毁灭💥"); true }  

// &&短路:左侧false时右侧不执行
false && 自毁程序()  // 无事发生  

// ||短路:左侧true时右侧不执行
核按钮按下 || 自毁程序()  // 只输出"地球毁灭"  

布尔实战禁忌手册 🚨

Kotlin 复制代码
    // 1、可空布尔刺杀案
    val 许可状态: Boolean? = null  
    if (许可状态 == true) { ... } // 必须显式对比true  
    if (许可状态 ?: false) { ... } // 安全操作符兜底  
    
    // 2、类型检测的卧底
    when (obj) {  
        is String -> println(obj.length)  // obj自动转型  
        is Int -> println(obj.toDouble())  // Int变Double  
    } 
    
    // 3、函数返回的诡雷
    // 错误示范:Boolean?可能返回null导致崩溃
    fun isVip(): Boolean? = if(付费) true else null

    // 正确做法:Boolean必须有明确值
    fun isVip() = 付费 != null
    
    // 4、断言敢死队
    val 文件 = requireNotNull(openFile()) // 断言失败立刻抛异常
    check(文件.size > 0) { "文件不能为空" }  // 带消息的自杀式检查

Boolean不容妥协的二元秩序

🔸 禁止 任何形式隐式转换或数值替代。

🔸 永远不用if(obj)替代if(obj != null)

🔸 类型检测后直接调用成员(编译器已斩首) 。

🔸 Boolean?必须用?:==显式处理。

🔸 xor解决非此即彼的排他逻辑


字符类型:Unicode宇宙的独立特工 🎭

KotlinChar绝非普通字母容器,而是携带16Unicode灵魂 的超级信使。本质是0~65535(U+0000~U+FFFF)的整数编码,却拒绝与数字家族同流合污!

核心特性解析

特性 示例 Java的血海深仇
Unicode直通车 val lightning = '\u26A1' Java必须Character.toChars()
单引号封印 val 字母K = 'K' 禁止双引号!"K"是字符串
非数字化基因 println('A'.code) 输出65,但禁止'A' == 65🚫
转义符超能力 val wrap = '\n' 支持\t \ '9大转义符
go 复制代码
// 在字符串中召唤诸神  
println("希腊字母Alpha:\u0391") // Α  
println("扑克大王:\uD83C\uDCA1") // 🂡 需要两个Char的代理对!

字符与整型的次元壁:强制隔离字符与数字

ini 复制代码
val num = 65  
val a = 'A'  

// 禁止直接比较!
if (a == 65) { /* 编译爆炸 💥 */ }  

// 正确穿越次元壁的姿势  
if (a.code == 65) { // ✅ 调用.code获取数字编码  
    println("65号特工确认!")  
}  

字符操作实战宝典

Kotlin 复制代码
// 1、大小写变形术
"kotlin".first().uppercaseChar()  // K → 链式调用取代Java的Character  

// 2、字符侦探工具包
'7'.isDigit()   // true:鉴定数字身份  
'β'.isLetter()  // true:检测文字血统
' '.isWhitespace() // true:识别隐形人

// 3、数字字符转型危机
val 虚假数字 = '9'.toInt()   // → 57(ASCII编码值)  
val 真实数值 = '9'.digitToInt() // → 9(这才是真身!)

// 4、范围迭代魔法
for (字母 in 'a'..'z') print(字母) // 直接遍历字母表!  
('α'..'ω').joinToString("") // 希腊字母全家福

实战三军规:

🔸 比较字符编码要用char.code而非直接数字。

🔸 转换数字字符必用digitToInt()

🔸 切割含emoji文本时祭出codePointCount()


字符串类型:文本的七十二变戏法 🪄

Kotlin字符串 不是字符的简单排列,而是自带魔法的文字精灵!它们能执行代码、吞掉复杂格式、甚至分裂重组------彻底终结Java时代的字符串炼狱

字符串的魔法基因

  • 1、模板表达式:变量寄生术 val 用户名 = "老王" val 待办事项 = listOf("修空调", "买西瓜") println(" <math xmlns="http://www.w3.org/1998/Math/MathML"> 用户名 . u p p e r c a s e ( ) 今天要 {用户名.uppercase()}今天要 </math>用户名.uppercase()今天要{待办事项[0]}和${待办事项[1]}") // 输出:老王今天要修空调和买西瓜 🔥 ​黑暗魔法规则​:

    • $变量名 直接寄生(遇到空格/标点自动停止)。
    • ${任意表达式} 可执行代码并吞噬结果。
    • 支持空安全操作${user?.name ?: "游客"}
  • 2、原生多行构造器:格式化核弹

    python 复制代码
    val 购物清单 = """
        1️⃣|苹果 × 3
        ⚡|西瓜 × 1
        🔧|空调维修工具 × 1
     """.trimMargin("⚡")  // 指定⚡为对齐标志

    👉 输出自动删除行首空格和⚡前缀,但保留换行:

    复制代码
    1️⃣|苹果 × 3
    西瓜 × 1
    🔧|空调维修工具 × 1
  • 3、字符切割风暴:切片艺术 val 身份证 = "11010519990101234X" val 出生年 = 身份证.slice(6..9) // "1999" val 校验位 = 身份证.last() // 'X'


字符串独门特技

  • 1、正则表达式无缝融合 val 价格文本 = "苹果:¥5.6/kg, 西瓜:¥15/个" val 价格正则 = Regex("""¥(\d+.?\d*)""") 价格正则.findAll(价格文本).forEach { println("找到价格: ${it.groupValues[1]}") } // 输出: 5.6 → 15

  • 2、安全转型防爆盾 val 用户输入 = "123a" 用户输入.toIntOrNull() ?: 0 // 返回0而不是崩溃

  • 3、字符级魔法实验室

    操作 代码示例 效果
    首字母大写 "kotlin".replaceFirstChar{it.uppercase()} "Kotlin"
    单词反转 "Hello.Kotlin".split(".").reversed().joinToString(".") "Kotlin.Hello"
    密码强度检测 "Abc123!".any{it.isUpperCase()} && "Abc123!".any{it.isDigit()} true
    隐藏敏感信息 "13800138000".replace(Regex("(\d{3})\d{4}(\d{4})"), "1∗∗∗∗2") "138*​**​*8000"

字符串地狱陷阱

kotlin 复制代码
    // 1、Emoji长度黑洞
    "👨👩👧👦".length      // 返回11 (实际1个字符)
    // 正确姿势:
    "👨👩👧👦".codePointCount(0, "👨👩👧👦".length) // 返回1
    
    // 2、子串切割惨案
    "我喜欢😊".substring(0,3) // 输出"我喜欢" ✅  
    "a😊b".substring(0,2)     // 输出"a?" ❌ (emoji被腰斩)
    // 安全方案:
    "a😊b".subSequence(0,3)   // 完整输出"a😊"
    
    // 3、==和equals()密码战
    val 官方文本 = "Kotlin"
    val 用户输入 = "kotlin".replaceFirstChar{it.uppercase()}

    官方文本 == 用户输入          // true (内容相同)
    官方文本 === 用户输入         // false (不同对象)
    官方文本.equals(用户输入, true) // true (忽略大小写)
    
    // 4、拼接性能刺客
    // 致命慢动作 (创建大量临时对象):
    var 结果 = ""
    for(i in 1..10000){
        结果 += i
    }

    // 光速方案 (预分配内存):
    buildString {
        for(i in 1..10000){
            append(i)
        }
    }

字符串生存法则 📜

  • 1、模板表达式优先原则
    当遇到变量+文本组合,立即使用"$变量文本",告别+拼接时代。
  • 2、多行文本圣约
    超过2行的文本必须用三重引号""",这是对\n+的终极复仇。
  • 3、Emoji处理三诫
    • 长度检测必用codePointCount()
    • 切割文本只用subSequence()
    • 避免直接操作[index]获取字符。
  • 4、转型安全协议:所有用户输入转换必须使用 .toIntOrNull() ?: 默认值 .toBooleanStrictOrNull() // 连"True/False"都不认!
  • 5、性能至上令
    • 循环拼接用StringBuilderbuildString{}
    • 频繁操作字符串用CharSequence视图。

Kotlin的独门秘籍:基本类型的变形法则 🤹‍♂️

无原始类型:西装暴徒的伪装术

Kotlin宣称"万物皆对象",连基本类型都是穿西装的原始类型​:

kotlin 复制代码
val 工资: Int = 8000 // 表面是类实例  
println(工资.javaClass.kotlin) // 输出:class kotlin.Int  

编译期魔术​:

arduino 复制代码
// 反编译字节码真相:  
int 实际工资 = 8000; // 自动拆箱成原始类型!  

👉 ​设计哲学​:

  • 源码层享受面向对象统一待遇(可调方法、实现接口)。
  • 字节码层蜕变为原始类型(性能与Java持平)。
  • 好比员工上班穿西装(代码优雅),下班换T恤(JVM高效)。

空安全封印术:次元壁的诞生

IntInt? 是编译器眼里的平行宇宙​:

特征 Int宇宙 Int?宇宙
内存占用 4字节(原始类型) 16字节(包装类+指针)
默认值 0 null
危险操作 可能触发NPE核爆 💥
典型应用场景 方法参数/非空属性 数据库字段/网络响应

破壁方法​:

kotlin 复制代码
val 可能空: Int? = null  
val 绝对存在: Int = 可能空 ?: -1 // 空合并操作符打通次元  

⚠️ ​性能警报 ​:

循环中频繁操作Int?会导致自动装箱灾难​!

kotlin 复制代码
var sum = 0  
for (i in 1..1000000) {  
    val 可空值: Int? = i  // 每次循环都new Integer(i)!  
    sum += 可空值 ?: 0   // 内存爆炸+GC风暴  
}  

类型推导魔术:编译器的读心术

Kotlin编译器像算命先生般预测你的意图:

kotlin 复制代码
val 存款 = 3000          // 自动推导为Int → 小钱用Int  
val 梦想存款 = 3000000000 // 自动升格为Long → 大钱用Long  
val 利率 = 3.5           // 默认Double → 浮点用高精度  

推导规则暗黑手册​:

  • 1、整数字面值
    • 不超过Int.MAX_VALUEInt
    • 超过或带L后缀 → Long
  • 2、浮点字面值
    • 默认 → Double
    • F/f后缀 → Float
  • 3、表达式传染 : val a = 100 // Int
    val b = a * 2.0 // Double (Int被传染升级)

内联类黑科技:类型替身术

kotlin 复制代码
@JvmInline  
value class UserId(val id: Int) // 编译期化身Int,运行时保留类型尊严  

fun 查询用户(userId: UserId) { ... }  

// 使用效果:  
val 伪Id = 10086  
查询用户(伪Id)          // ❌ 编译报错!要求UserId类型  
查询用户(UserId(10086)) // ✅  

三大神效​:

  • 1、零运行时开销:运行时就是原始类型。
  • 2、类型安全强化 :禁止普通Int混入。
  • 3、语义化增强UserIdInt更表达意图。

⚠️ ​限制条款​:

  • 必须有且仅有一个val属性。
  • 不能继承或被继承。
  • 目前仍在进化中(Kotlin 1.9+完善)。

总结

Kotlin把基础类型炼成了精怪!表面是Java老友,背地里玩智能转换空安全封印类型推导 三连招。这些​"筑基材料"​带着编译器外挂------好比用智能钢筋盖楼,自动避开裂缝歪斜。

当数字带问号(Int?)意味着危险信号;字符能直接召唤Emoji神龙;字符串三重引号是排版神器。🎯 打牢这块基石,后面函数与对象的高楼才不会轰然倒塌

欢迎一键四连关注 + 点赞 + 收藏 + 评论

相关推荐
小趴菜82277 小时前
安卓接入Kwai广告源
android·kotlin
2501_916013747 小时前
iOS 混淆与 App Store 审核兼容性 避免被拒的策略与实战流程(iOS 混淆、ipa 加固、上架合规)
android·ios·小程序·https·uni-app·iphone·webview
程序员江同学8 小时前
Kotlin 技术月报 | 2025 年 9 月
android·kotlin
码农的小菜园9 小时前
探究ContentProvider(一)
android
时光少年10 小时前
Compose AnnotatedString实现Html样式解析
android·前端
hnlgzb11 小时前
安卓中,kotlin如何写app界面?
android·开发语言·kotlin
jzlhll12311 小时前
deepseek kotlin flow快生产者和慢消费者解决策略
android·kotlin
火柴就是我12 小时前
Android 事件分发之动态的决定某个View来处理事件
android
一直向钱12 小时前
FileProvider 配置必须针对 Android 7.0+(API 24+)做兼容
android
zh_xuan12 小时前
Android 消息循环机制
android