值類:Kotlin中的零成本抽象

Kotlin的值類(Value Class)是一種強大的類型安全工具,允許開發者創建語義明確的類型,并保持運行時零成本。

假設系統中存在用戶的概念,用戶擁有名字和電子郵箱地址。用戶名和電子郵箱地址都是長度不超過120個字符的字符串。用戶名不能是空白,不能是"null",也不能包含"@"。電子郵箱地址必須包含"@"。根據這些要求,我們可以得到一個簡單的模型。

代碼1??簡單的User模型

data class User(val name: String, val email: String)

這個模型沒有對值進行校驗,客戶端代碼可能直接調用?user.name =?"null"?,產生一條不滿足業務約束的數據。為了避免這種情況,我們可以為用戶名、電子郵箱分別建立模型。

代碼2??復雜的User模型

data class User(val name: UserName, val email: Email)class UserName(val value: String) {init {require(!value.contains("@") && ... ) { "Invalid userName" }}
}class Email(val value: String) {init {require(value.contains("@")) { "Invalid email" }}
}

復雜模型可以保證業務邏輯不出錯,但多了一個包裝對象,產生運行時性能損耗。仔細觀察UserName和Email兩個類,都是把一個String對象和一些專屬操作綁定起來,構成一個新類型。新類型可以表達語義,操作可以校驗值。這兩樣都是我們需要的。有沒有辦法既能做到這兩點,又不會產生額外的包裝對象呢?答案就是值類。

代碼3??值類:“基礎”類型零成本抽象

@JvmInline
value class UserName(val value: String) {init {require(!value.contains("@") && ... ) { "Invalid userName" }}}

從語法上看,值類版本的UserName只比普通版本多了?@JvmInline?注釋,并且將?class?換成了?value?class?,其他方面并無差別。但在運行時,值類不會產生額外性能損耗,可以做到零成本抽象。

值類能做到運行時零成本的方法和C++模板或TypeScript類似,編譯時在字節碼級別進行內聯。比如下面的值類

@JvmInline
value class Meter(val value: Double)fun calculate(m: Meter) = m.value * 2

編譯后的字節碼等價于

public static double calculate(double m) {return m * 2;
}

因此值類可以做到:

  • 沒有額外對象分配
  • 沒有虛方法表
  • 沒有對象頭開銷
  • 方法調用轉為靜態分派

當然值類的使用也存在一些限制,包括:

  • 不能聲明多個屬性
  • 不能繼承其他類(可以實現接口)
  • 不能在反射場景中使用
  • 需要特殊處理泛型場景

JVM泛型需要對象,因此在泛型中使用值類會引發裝箱。

// 觸發裝箱
val list = listOf(UserId("123")) // 方案1:使用原始類型數組避免裝箱(推薦)
val array = arrayOf(UserId("123"))// 方案2:通過inline class+類型投影減少裝箱
val list = listOf<UserId>(UserId("123"))

值類的使用場景有:

  • 需要區分語義相似的原始類型時 (名字, 郵件等)
  • 需要為簡單值添加領域行為時
  • 高頻調用的基礎類型包裝
  • 要求極致性能的數值計算場景
  • 大型項目中的領域模型定義

需要避免值類的場景有:

  • 需要包裝多個字段的復雜對象
  • 需要復雜繼承關系的類型
  • 深度依賴反射的操作
  • 與某些Java框架深度集成的場景

值類的核心優勢在于:

  1. 編譯時類型安全
  2. 領域語義明確
  3. 零成本抽象
  4. 減少模型轉換樣板
  5. 增強代碼可讀性和可維護性
表1??值類和數據類對比
特性值類數據類(Data Class)
內存開銷零(運行時內聯)每個對象額外16-24字節對象頭
適用場景單值包裝多屬性數據容器(如DTO)
自動生成方法僅基于包裝值的方法equals()/hashCode()/copy()等
泛型處理可能觸發裝箱直接支持
表2??值類與裝箱對比
特性值類裝箱(以Integer為例)
設計目標類型安全的語義增強原始類型與對象類型的轉換橋梁
內存開銷0 (編譯時內聯)Integer: 16+字節對象頭
類型系統創建真正的新類型int和Integer是相同值的不同表示
空值安全默認非空 (顯式聲明可空)int不能null, Integer可為null
集合性能等同于原始類型集合對象指針集合 (內存碎片化)
使用場景領域建模中的語義化類型泛型兼容和對象類型需求
表3??值類與值對象對比
維度值類DDD值對象 (Value Object)
范疇編程語言特性 (Kotlin特有)領域驅動設計(DDD)概念
核心目的零開銷的類型安全包裝表示沒有唯一標識的領域概念
實現方式@JvmInline value class不可變類(通常用 data class)
身份標識無明確要求無唯一標識 (靠屬性值區分)
相等性基于包裝值 (可自定義)基于所有屬性值
可變性默認可變 (但通常設計為不可變)嚴格不可變
典型應用ID包裝、單位封裝、類型別名金額、地址、日期范圍、坐標點

值對象(Value Object)是領域驅動設計中不可變的概念片段,值類是Kotlin零開銷的類型安全包裝特性。二者主要是名稱相似。如果當值對象只需封裝單個值時,值類是最佳實現方式。

表4??值類和擴展方法
維度值類擴展方法
本質創建新類型擴展現有類型
類型系統編譯時引入新類型 (運行時內聯)不引入新類型
作用范圍全局性的類型安全增強局部性的功能增強
主要目的解決類型安全問題解決功能擴展問題
使用方式創建新類型實例在現有類型實例上調用
性能影響零運行時開銷極低開銷(靜態方法調用)
領域建模核心領域概念建模輔助功能實現

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83877.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83877.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83877.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

arm64版BC-liunx-for-euler與X86_64版OpenEuler從源碼安裝git-lfs

1.arm64版BC-liunx-for-euler安裝git-lfs 檢查系統版本信息 uname -a Linux bms-42068966-004 5.10.0-136.49.0.127.10.oe2203.bclinux.aarch64 #1 SMP Tue Oct 10 14:09:09 CST 2023 aarch64 aarch64 aarch64 GNU/Linux 下載git-lfs構建腳本和源碼 git clone https://gite…

2025國家衛健委減肥食譜PDF完整版(免費下載打印)

《成人肥胖食養指南&#xff08;2024年版&#xff09;》發布&#xff1a;科學減肥&#xff0c;從這里開始? 在這個追求健康與美的時代&#xff0c;減肥成為了許多人關注的熱點話題。國家衛健委正式發布了《成人肥胖食養指南&#xff08;2024年版&#xff09;》&#xff0c;為我…

Android 手機如何實現本地視頻音頻提取?實戰教程來了

我們經常會遇到這樣的需求&#xff1a;比如看到一段喜歡的短視頻&#xff0c;想把里面的背景音樂保存下來&#xff1b;或者需要從一段課程視頻中提取語音內容用于學習。這時候&#xff0c;將手機視頻轉換成 MP3 音頻就是一個非常實用的功能。 今天就來教大家如何使用一款簡單好…

STM32項目---汽車氛圍燈

一、藍牙模塊驅動 1、怎么使用藍牙模塊呢&#xff1f; 1&#xff1a;首先&#xff0c;先通過串口調試助手驗證藍牙模塊是否正常使用。先連接好 2&#xff1a;打開串口調試軟件配置好 3&#xff1a;發送測試指令&#xff1a;AT\r\n,返回OK&#xff0c;則說明連接正確&#xff…

python+uniapp微信小程序的共享雨傘租賃系統

目錄 技術棧介紹具體實現截圖系統設計研究方法&#xff1a;設計步驟設計流程核心代碼部分展示研究方法詳細視頻演示試驗方案論文大綱源碼獲取/詳細視頻演示 技術棧介紹 Django-SpringBoot-php-Node.js-flask 本課題的研究方法和研究步驟基本合理&#xff0c;難度適中&#xf…

一次生產故障引發的JVM垃圾回收器選型思考:徹底掌握垃圾回收原理及通用配置!

寫在前面的話 前幾天凌晨2點&#xff0c;我被一通電話驚醒——線上交易系統出現了嚴重的延遲問題&#xff0c;用戶支付請求響應時間從平時的100ms飆升到了5秒&#xff0c;客服電話都被打爆了。 經過緊急排查&#xff0c;我們發現罪魁禍首竟然是JVM的垃圾回收器&#xff01;當…

學習日記-day30-6.15

完成目標&#xff1a; 知識點&#xff1a; 1.DDL和DML的補充 知識點 核心內容 重點 快速創建表 使用CREATE TABLE...AS SELECT語句基于現有表快速創建新表 結構和數據復制 vs 僅復制結構&#xff08;WHERE 12&#xff09; 數據刪除操作 DELETE FROM逐條刪除 vs TRUNCAT…

從檢測到智能質控:IACheck如何成為TIC機構的AI中臺?

一、TIC行業為何亟需AI質控&#xff1f; 過去十年&#xff0c;中國的TIC&#xff08;Testing, Inspection, Certification&#xff09;行業年均增長超過10%。無論是消費品、環境監測&#xff0c;還是工業制造、出口貿易&#xff0c;對“第三方檢測報告”的依賴程度持續加深。 …

cka-1.32考題

1、HPA自動擴縮容 考題 &#xff08;考試的考題內容&#xff0c;只有下面方框里的內容&#xff09; 你必須連接到正確的主機。不這樣做可能導致零分。 [candidatebase] $ ssh cka000050 Task 在 autoscale namespace 中創建一個名為 apache-server 的新 HorizontalPodAut…

DeepSeek 技術原理詳解

引言 DeepSeek是一種基于Transformer架構的大型語言模型&#xff0c;它在自然語言處理領域展現出了卓越的性能。本文將深入探討DeepSeek的技術原理&#xff0c;包括其架構設計、訓練方法和優化策略&#xff0c;并結合代碼實現進行詳細講解。 Transformer基礎架構 DeepSeek基…

組件化 websocket

實時數據響應&#xff0c;組件化websocket減少代碼冗余 組件定義 websocket.vue <template><div></div> </template><script>export default {data() {return {webSocket: null, // webSocket實例lockReconnect: false, // 重連鎖&#xff0c;…

IBMS集成系統3D可視化數字孿生管理平臺介紹、搭建、運維

IBMS集成系統3D可視化數字孿生管理平臺介紹、搭建、運維 IBMS集成系統3D可視化數字孿生管理平臺是一種先進的智能建筑管理系統&#xff0c;通過數字孿生技術和3D可視化界面&#xff0c;實現對建筑設施的全方位、智能化管理。該平臺整合了物聯網(IoT)、大數據、人工智能和三維建…

湖北理元理律師事務所:債務重組中的技術賦能與法律邊界

一、當法律遇上算法&#xff1a;還款模型的進化 傳統債務協商依賴律師經驗&#xff0c;如今通過技術工具可實現&#xff1a; 輸入&#xff1a;用戶收入/債務/必需支出 輸出&#xff1a; 1. 法定可減免金額&#xff08;基于LPR與歷史判例庫&#xff09;&#xff1b; 2.…

對抗串擾的第一武器

痕量分離;長度平行度;stackup&#xff1a;有沒有一個脫穎而出&#xff1f; 我已經有一段時間沒有看到關于串擾的文章了&#xff0c;所以我決定借此機會為那些可能對為什么精通串擾的 PCB 設計人員和硬件工程師使用各種設計規則來控制串擾感興趣的 PCB 設計社區中的人簡要介紹一…

FastAPI:(11)SQL數據庫

FastAPI&#xff1a;(11)SQL數據庫 由于CSDN無法展示「漸構」的「#d&#xff0c;#e&#xff0c;#t&#xff0c;#c&#xff0c;#v&#xff0c;#a」標簽&#xff0c;推薦訪問我個人網站進行閱讀&#xff1a;Hkini 「漸構展示」如下&#xff1a; #c 概述 文章內容概括 #mermaid…

“智眸·家聯“項目開發(一)

嵌入式開發調試知識點總結&#xff08;含操作流程&#xff09; 我們今天解決問題的過程&#xff0c;就像是偵探破案&#xff0c;從最表面的線索&#xff08;網絡不通&#xff09;開始&#xff0c;一步步深入&#xff0c;最終找到了案件的核心&#xff08;硬件不匹配&#xff0…

展開說說Android之Retrofit詳解_使用篇

Retrofit是由Square公司開發的類型安全HTTP客戶端框架&#xff0c;借助動態代理在運行時生成接口實現類&#xff0c;將注解轉化為OkHttp請求配置&#xff1b;節省成本通過轉換器(Gson/Moshi)自動序列化JSON/XML&#xff0c;內部處理網絡請求在主線程返回報文。Retrofit 直譯是封…

復古美學淺綠色文藝風格Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色介紹 復古美學淺綠色文藝風格 Lr 調色&#xff0c;是基于 Adobe Lightroom&#xff08;Lr&#xff09;軟件&#xff0c;為攝影作品賦予特定藝術氛圍的調色方式。通過合理設置軟件中的各項參數與工具&#xff0c;把照片調整為以淺綠色為主調&#xff0c;融合復古元素與文藝氣…

力扣網C語言編程題:缺失的第一個正數第三種解題方法

一. 簡介 前面文章學習了對該題目的兩種解題思路&#xff0c;文章如下&#xff1a; 力扣網C語言編程題&#xff1a;缺失的第一個正數-CSDN博客 但是前面的實現上在空間復雜度上沒有滿足要求。本文學習一種在空間復雜度上為 O(1)的思路。 二. 力扣網C語言編程題&#xff1a;缺…

PyTorch 實現 MNIST 手寫數字識別

PyTorch 實現 MNIST 手寫數字識別 MNIST 是一個經典的手寫數字數據集&#xff0c;包含 60000 張訓練圖像和 10000 張測試圖像。使用 PyTorch 實現 MNIST 分類通常包括數據加載、模型構建、訓練和評估幾個部分。 數據加載與預處理 使用 torchvision 加載 MNIST 數據集&#x…