異常處理小妙招——3.構造函數的安全第一原則:為什么不在構造函數中拋出異常?

文章目錄

    • 災難性的生日派對
    • 構造函數:對象的出生證明
    • 安全第一:嚴格的出生檢查
    • 為什么要在構造函數中嚴格驗證?
      • 1. 避免"僵尸對象"
      • 2. Fail-Fast(快速失敗)原則
    • 現實世界的實踐建議
      • 1. 使用工廠方法模式
      • 2. 使用Builder模式處理復雜驗證
    • 結論:做嚴格的門衛,而不是友好的迎賓員

想象一下,你正在招聘一名銀行金庫管理員。你會選擇一個對每個人都不加檢查就放行的人,還是一個嚴格驗證每個進入者身份的門衛?

在編程世界中,構造函數就是這個門衛,而"安全第一"原則就是它的工作準則。

災難性的生日派對

去年,我幫朋友組織一個生日派對。我們使用了一個簡單的注冊系統:

public class PartyGuest {private String name;private int age;public PartyGuest(String name, int age) {this.name = name;this.age = age;// 這里沒有驗證年齡!}public void serveAlcohol() {if (age < 18) {System.out.println("只能提供果汁");} else {System.out.println("提供啤酒");}}
}

結果發生了什么?有人傳入了負數的年齡值-5,系統沒有檢查,最終導致服務邏輯混亂。這就像門衛讓一個自稱"-5歲"的人進入派對一樣荒謬!

構造函數:對象的出生證明

每個對象在創建時都會調用構造函數。這就像是對象的出生時刻。如果在出生時就有先天性問題,這個對象的一生都會充滿風險。

// 有問題的做法:讓先天缺陷的對象誕生
public class BankAccount {private double balance;public BankAccount(double initialBalance) {// 沒有驗證初始余額是否合法this.balance = initialBalance;}
}// 潛在災難:余額為負的賬戶開始運作
BankAccount account = new BankAccount(-1000); // 一開始就是債務!

安全第一:嚴格的出生檢查

好的構造函數應該像嚴格的產房醫生,確保每個"新生兒"都是健康的:

public class BankAccount {private double balance;public BankAccount(double initialBalance) {if (initialBalance < 0) {throw new IllegalArgumentException("初始余額不能為負數:¥" + initialBalance);}if (initialBalance > 1_000_000) {throw new IllegalArgumentException("初始余額過高,需要額外驗證:¥" + initialBalance);}this.balance = initialBalance;System.out.println("賬戶創建成功,初始余額:¥" + initialBalance);}
}

為什么要在構造函數中嚴格驗證?

1. 避免"僵尸對象"

半初始化對象就像僵尸——既不是活的也不是死的,只會帶來麻煩:

public class DatabaseConnection {private Connection conn;public DatabaseConnection(String url) {// 忘記初始化連接!// 現在conn為null,但對象還是被創建了}public void query(String sql) {conn.createStatement(); // 運行時才拋出NullPointerException!}
}

2. Fail-Fast(快速失敗)原則

早點發現問題,比讓問題潛伏到運行時好得多:

// 快速失敗:立即發現問題
public class TemperatureController {private double temperature;public TemperatureController(double temp) {if (temp < -273.15) {throw new IllegalArgumentException("溫度不能低于絕對零度");}this.temperature = temp;}
}// 立即報錯:new TemperatureController(-300); 
// 而不是在運行時導致設備損壞

現實世界的實踐建議

1. 使用工廠方法模式

當構造過程復雜時,使用工廠方法:

public class Employee {private String name;private int id;private Employee(String name, int id) {this.name = name;this.id = id;}public static Employee create(String name, int id) {if (name == null || name.trim().isEmpty()) {throw new IllegalArgumentException("員工姓名不能為空");}if (id <= 0) {throw new IllegalArgumentException("員工ID必須為正數");}return new Employee(name, id);}
}

2. 使用Builder模式處理復雜驗證

當有多個參數需要驗證時:

public class UserProfile {private final String email;private final String username;private UserProfile(Builder builder) {this.email = builder.email;this.username = builder.username;}public static class Builder {private String email;private String username;public Builder email(String email) {if (!isValidEmail(email)) {throw new IllegalArgumentException("無效的郵箱格式");}this.email = email;return this;}public Builder username(String username) {if (username == null || username.length() < 3) {throw new IllegalArgumentException("用戶名至少3個字符");}this.username = username;return this;}public UserProfile build() {return new UserProfile(this);}private boolean isValidEmail(String email) {return email != null && email.contains("@");}}
}// 使用方式
UserProfile user = new UserProfile.Builder().email("test@example.com").username("alice").build();

結論:做嚴格的門衛,而不是友好的迎賓員

在代碼世界中,構造函數應該扮演嚴格門衛的角色,而不是友好迎賓員。它的工作是確保只有完全有效、合規的對象才能被創建。

記住:在構造函數中拋出異常不是壞事——它防止了更壞的事情發生。一個在創建時就失敗的對象,遠比一個在運行時才表現出異常行為的對象要好得多。

下次編寫構造函數時,問問自己:我的這個"門衛"夠嚴格嗎?它是否檢查了所有必要的憑證?如果不是,那么是時候加強安保措施了!


本文靈感來源于生產環境中的一次真實事故:一個未經驗證的構造函數導致系統創建了數千個無效對象,最終引發級聯故障。教訓:安全第一,從不妥協。

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

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

相關文章

iptables 和 ip route

文章目錄iptables原理及常用命令表鏈鏈表鏈表總結iptables 常用命令及參數1. 規則管理命令 (Commands)2. 規則匹配參數 (Rule-Specification - Matches)3. 目標動作參數 (Target)命令示例配置流程示例ip route常用命令iptables和ip route的聯系實用命令示例對比iptables原理及常…

RPC和HTTP的區別?

RPC和HTTP是兩種不同的通信協議&#xff0c;它們在通信方式、性能效率以及靈活性可擴展性等方面存在區別。以下是具體分析&#xff1a; 通信方式 RPC&#xff1a;RPC是基于遠程過程調用的二進制協議&#xff0c;它允許客戶端像調用本地函數一樣調用遠程服務器上的函數或方法[2]…

貝葉斯分類(Bayes Classify)

一. 核心思想貝葉斯分類是一類基于貝葉斯定理&#xff08;Bayes Theorem&#xff09;和概率統計的分類算法&#xff0c;核心思想是 “通過已知的先驗概率&#xff0c;結合數據的似然性&#xff0c;計算后驗概率&#xff0c;最終將樣本歸為后驗概率最高的類別”。它在機器學習、…

怎么熟悉業務,我是做前端的,但對業務了解沒有渠道

作為前端開發者&#xff0c;想深入了解業務但“沒有渠道”&#xff0c;這是非常普遍的痛點。很多前端同學只接到“切圖實現頁面”的任務&#xff0c;久而久之就成了“實現工具人”。但業務理解力&#xff0c;恰恰是區分“初級”和“高級”前端的核心分水嶺。 好消息是&#xff…

如何批量在PDF文檔最后一頁蓋章?

在面對上百份需要處理的 PDF 文檔時&#xff0c;逐個打開文檔蓋章再進行保存&#xff0c;這些步驟不僅提高我們工作的繁瑣&#xff0c;還容易導致處理位置錯誤或遺漏。那么怎么去將 PDF 文檔末頁實現批量自動打上電子印章&#xff1f;一般的方式沒有辦法來滿足我們高效率辦公的…

Keras/TensorFlow 中 `predict()` 函數詳細說明

Keras/TensorFlow 中 predict() 函數詳細說明 predict() 是 Keras/TensorFlow 中用于模型推理的核心方法&#xff0c;用于對輸入數據生成預測輸出。下面我將從多個維度全面介紹這個函數的用法和細節。 一、基礎語法和參數 基本形式 predictions model.predict(x,batch_sizeNon…

題解:UVA1589 象棋 Xiangqi

看到代碼別急著走&#xff0c;還要解釋呢&#xff01;哈哈&#xff0c;知道這個題我是怎么來的嗎&#xff1f;和爸爸下象棋20場輸17場和2場QWQ于是乎我就想找到一個可以自動幫我下棋的程序&#xff0c;在洛谷上面搜索&#xff0c;就搜索到了這個題。很好奇UVA的為啥空間限制是0…

基于YOLOv11的腦卒中目標檢測及其完整數據集——推動智能醫療發展的新機遇!

在當今科技迅速發展的時代&#xff0c;腦卒中作為一種嚴重威脅人類健康的疾病&#xff0c;其早期的檢測和及時的干預顯得尤為重要。為此&#xff0c;本項目推出基于YOLOv11的腦卒中目標檢測系統&#xff0c;結合完整的數據集&#xff0c;不僅提高了檢測的效率&#xff0c;更為醫…

sed——Stream Editor流編輯器

文章目錄前言一、什么是sed二、sed的原理2.1 sed工作流程的三個步驟2.2 sed的兩個重要空間&#xff1a;2.3 sed的具體運作流程三、sed的常見用法3.1 sed的基本格式3.2 常用選項3.3 常用操作3.3.1 基本語法規則3.3.2 常用操作命令3.4 操作用法示例3.4.1 輸出符合條件的文本&…

Zotero白嫖騰訊云翻譯

Zotero白嫖騰訊云無限制字數翻譯 文章目錄Zotero白嫖騰訊云無限制字數翻譯1、安裝插件1、登錄騰訊云2、找到訪問管理進入3、創建一個子用戶4、啟用機器翻譯功能5、復制秘鑰6、設置到Zotero1、安裝插件 zotero-pdf-translate&#xff1a;https://github.com/windingwind/zotero…

TCP多進程和多線程并發服務

進程和線程的區別&#xff1a; 詳細的可以參考這樣文檔進程和線程的區別(超詳細)-CSDN博客 核心比喻 進程 一個工廠&#xff1a;這個工廠擁有獨立的資源&#xff08;廠房、原材料、資金、電力&#xff09;。每個工廠之間是相互隔離的&#xff0c;一個工廠著火…

計算機畢業設計springboot基于Java+Spring的疫苗接種管理系統的設計與實現 基于Spring Boot框架的疫苗接種信息管理系統開發與應用 Java與Spring技術驅動的疫苗接種管理

計算機畢業設計springboot基于JavaSpring的疫苗接種管理系統的設計與實現69geq9 &#xff08;配套有源碼 程序 mysql數據庫 論文&#xff09; 本套源碼可以在文本聯xi,先看具體系統功能演示視頻領取&#xff0c;可分享源碼參考。隨著信息技術的飛速發展&#xff0c;計算機技術在…

C/C++圣誕樹①

寫在前面 圣誕節將至&#xff0c;我總想用代碼做點什么&#xff0c;來表達對這個溫馨節日的敬意。于是&#xff0c;我決定用C語言在控制臺中繪制一幅充滿節日氣氛的圣誕樹畫面。它不僅有閃爍的雪花、五彩的燈光&#xff0c;還有一顆顆精心雕琢的心形圖案&#xff0c;仿佛把整個…

【小白入】顯示器核心參數對比度簡介

對比度是一個非常核心的顯示器參數。下面我們來了解一下。一、核心定義&#xff1a;什么是對比度&#xff1f;顯示器的對比度&#xff08;Contrast Ratio&#xff09;是指其最亮狀態&#xff08;白色&#xff09;與最暗狀態&#xff08;黑色&#xff09;之間的亮度比值。簡單來…

【項目】多模態RAG必備神器—olmOCR重塑PDF文本提取格局

【項目】多模態RAG必備神器—olmOCR重塑PDF文本提取格局&#xff08;一&#xff09;olmOCR是什么&#xff1f;&#xff08;二&#xff09;olmOCR 的核心技術&#xff08;1&#xff09;文檔錨定技術&#xff08;2&#xff09;微調 7B 視覺語言模型&#xff08;三&#xff09;olm…

解決Android Studio查找aar源碼的錯誤

我又來給大模型貢獻素材了&#xff01; 問題 在更新了Android Studio Narwhal Feature Drop | 2025.1.2 Patch 1版本之后&#xff0c;遇到了一個問題&#xff0c;很煩人&#xff01;AS每次更新都能搞出點新毛病&#xff0c;真的服了。使用離線依賴aar包引入某個庫之后&#xff…

華為HCIP、HCIE認證:自學與培訓班的抉擇

大家好&#xff0c;這里是G-LAB IT實驗室。 在追求個人職業發展的道路上&#xff0c;取得華為的HCIP或HCIE認證是許多IT從業者的重要目標之一。 但在備考過程中&#xff0c;我們常常面臨一個選擇&#xff1a;是自學還是報名參加培訓班&#xff1f;本文將針對這個問題&#xff0…

空調噪音不穿幫,聲網虛擬直播降噪技巧超實用

虛擬主播團隊負責人來吐槽&#xff01;實時互動是核心&#xff0c;可主播回應慢半拍、動作表情跟不上語音&#xff0c;用戶立馬覺得假&#xff0c;嘩嘩流失。之前方案端到端延遲 700ms&#xff0c;互動總慢一步。直到接入商湯日日新大模型和聲網合作方案&#xff0c;延遲壓到 5…

Spark和Spring整合處理離線數據

如果你比較熟悉JavaWeb應用開發&#xff0c;那么對Spring框架一定不陌生&#xff0c;并且JavaWeb通常是基于SSM搭起的架構&#xff0c;主要用Java語言開發。但是開發Spark程序&#xff0c;Scala語言往往必不可少。 眾所周知&#xff0c;Scala如同Java一樣&#xff0c;都是運行…

智能高效內存分配器測試報告

一、項目背景 這個項目是為了學習和實現一個高性能、特別是高并發場景下的內存分配器。這個項目是基于谷歌開源項目tcmalloc(Thread-Caching Malloc)實現的。tcmalloc 的核心目標就是替代系統默認的 malloc/free&#xff0c;在多線程環境下提供更高效的內存管理。C/C的malloc雖…