【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神龙;字符串三重引号是排版神器。🎯 打牢这块基石,后面函数与对象的高楼才不会轰然倒塌

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

相关推荐
沅霖1 小时前
下载Android studio
android·ide·android studio
xzkyd outpaper1 小时前
Kotlin 协程线程切换机制详解
android·开发语言·kotlin
Near_Li2 小时前
uniapp-使用mumu模拟器调试安卓APP
android·uni-app
zhangphil3 小时前
Android MediaMetadataRetriever取视频封面,Kotlin(1)
android·kotlin
onthewaying6 小时前
详解 Android GLSurfaceView 与 Renderer:开启你的 OpenGL ES 之旅
android·opengl
aqi006 小时前
FFmpeg开发笔记(八十)使用百变魔音AiSound实现变声特效
android·ffmpeg·音视频·直播·流媒体
xzkyd outpaper7 小时前
Android中RecyclerView基本使用
android
我命由我123458 小时前
Android 开发问题:The specified child already has a parent.
android·java·开发语言·java-ee·android jetpack·android-studio·android runtime
三雒9 小时前
凡猿修仙传: Android SO 压缩方案 Nano
android