1. 概述
本教程將重點介紹和描述 <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/Assert.html">Spring <em >Assert</em></a> 類及其目的,並演示如何使用它。
2. Assert 類目的
Spring Assert 類幫助我們驗證參數。通過使用Assert 類的方法,我們可以編寫假設,即我們期望為真的內容。如果這些假設不成立,則會拋出運行時異常。
每個Assert 方法都可以與 Java 的 assert 語句進行比較。Java assert 語句如果在條件不滿足時會拋出 Error 異常。有趣的是,這些斷言可以被禁用。
以下是 Spring Assert 方法的一些特點:
- Assert 的方法是靜態的
- 它們會拋出 IllegalArgumentException 或 IllegalStateException
- 第一個參數通常是用於驗證的參數或要檢查的邏輯條件
- 最後一個參數通常是驗證失敗時顯示的錯誤消息
- 消息可以作為 String 參數或 Supplier<String> 參數傳遞
請注意,儘管名稱相似,Spring 斷言與 JUnit 和其他測試框架中的斷言沒有任何關係。Spring 斷言不是用於測試,而是用於調試。
3. 使用示例
定義一個 Car 類,幷包含一個公共方法 drive():
public class Car {
private String state = "stop";
public void drive(int speed) {
Assert.isTrue(speed > 0, "speed must be positive");
this.state = "drive";
// ...
}
}我們可以看出速度必須是一個正數。上述行是檢查條件的一種簡便方法,如果條件不滿足,則會拋出異常:
if (!(speed > 0)) {
throw new IllegalArgumentException("speed must be positive");
}每個 Assert 公共方法包含大致如下的代碼——一個條件塊,其中包含應用程序無法恢復的運行時異常。
如果我們嘗試使用負數作為參數調用 drive() 方法,將會拋出 IllegalArgumentException 異常:
Exception in thread "main" java.lang.IllegalArgumentException: speed must be positive4. 邏輯斷言
4.1. isTrue()
這段斷言在上文已討論過。它接受一個 布爾值條件,當條件為假時會拋出 IllegalArgumentException。
4.2. state()
方法 state() 與 isTrue() 具有相同的簽名,但會拋出 IllegalStateException。
正如其名稱所示,它應該在對象非法狀態下繼續執行的方法時使用。
假設我們不能在汽車正在行駛時調用 fuel() 方法。 讓我們在這種情況下使用 state() 斷言:
public void fuel() {
Assert.state(this.state.equals("stop"), "car must be stopped");
// ...
}當然,我們當然可以使用邏輯斷言來驗證一切。為了提高代碼的可讀性,我們還可以使用額外的斷言,使我們的代碼更具表達力。
5. 對象和類型斷言
5.1. notNull()
我們可以通過使用 notNull() 方法來假設一個對象不是 null 的:
public void сhangeOil(String oil) {
Assert.notNull(oil, "oil mustn't be null");
// ...
}5.2. isNull()</h3
另一方面,我們可以使用 isNull() 方法來檢查對象是否為 null。
public void replaceBattery(CarBattery carBattery) {
Assert.isNull(
carBattery.getCharge(),
"to replace battery the charge must be null");
// ...
}5.3. <em isInstanceOf()</em>
要檢查一個對象是否為特定類型的實例,我們可以使用 方法:
public void сhangeEngine(Engine engine) {
Assert.isInstanceOf(ToyotaEngine.class, engine);
// ...
}在我們的示例中,檢查成功通過,因為 ToyotaEngine 是 Engine 的子類。
5.4. isAssignable()
為了檢查類型,我們可以使用 Assert.isAssignable():
public void repairEngine(Engine engine) {
Assert.isAssignable(Engine.class, ToyotaEngine.class);
// ...
}兩個最近的斷言代表一種 is-a 關係。
6. 文本斷言
文本斷言用於對 String 類型的參數進行檢查。
6.1. hasLength()
我們可以通過使用 hasLength() 方法來檢查一個 String 是否非空,這意味着它至少包含一個空白字符。
public void startWithHasLength(String key) {
Assert.hasLength(key, "key must not be null and must not the empty");
// ...
}6.2. hasText()
我們可以通過使用 hasText() 方法,加強條件並檢查一個 String 是否包含至少一個非空白字符:
public void startWithHasText(String key) {
Assert.hasText(
key,
"key must not be null and must contain at least one non-whitespace character");
// ...
}6.3. doesNotContain()
我們可以通過使用 doesNotContain() 方法來確定一個字符串參數是否不包含特定的子字符串:
public void startWithNotContain(String key) {
Assert.doesNotContain(key, "123", "key mustn't contain 123");
// ...
}7. 集合和映射斷言
在斷言中,我們通常會檢查某個值是否滿足某個條件。對於集合和映射,我們需要專門的斷言來驗證它們的結構和內容。
集合斷言
-
containsKey(key): 驗證集合中是否包含指定鍵。assertTrue(mySet.containsKey("key")); -
containsValue(value): 驗證集合中是否包含指定值。assertTrue(myMap.containsValue(10)); -
size(): 驗證集合的大小是否符合預期。assertEquals(5, mySet.size());
映射斷言
-
containsKey(key): 驗證映射中是否包含指定鍵。assertTrue(myMap.containsKey("key")); -
containsValue(value): 驗證映射中是否包含指定值。assertTrue(myMap.containsValue(10)); -
size(): 驗證映射的大小是否符合預期。assertEquals(5, myMap.size());
7.1. 使用 notEmpty() 處理集合
正如其名稱所示,notEmpty() 方法斷言一個集合不為空,這意味着它既不是 null 也包含至少一個元素:
public void repair(Collection<String> repairParts) {
Assert.notEmpty(
repairParts,
"collection of repairParts mustn't be empty");
// ...
}7.2. notEmpty() 用於 Map
相同的該方法也針對 Map 進行了重載,我們可以檢查 Map 是否為空,並且至少包含一個條目:
public void repair(Map<String, String> repairParts) {
Assert.notEmpty(
repairParts,
"map of repairParts mustn't be empty");
// ...
}8. 數組斷言
數組斷言是一種用於驗證數組內容是否符合預期值的技術。當數組內容與預期不符時,斷言會拋出錯誤或異常,從而幫助開發者及早發現潛在問題。
以下是一些常見的數組斷言示例:
// 檢查數組長度是否為預期值
const myArray = [1, 2, 3, 4, 5];
const expectedLength = 5;
const actualLength = myArray.length;
if (actualLength !== expectedLength) {
throw new Error("數組長度不正確");
}
// 檢查數組元素是否在預期範圍內
const numbers = [10, 20, 30, 40, 50];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < 0 || numbers[i] > 100) {
throw new Error("數組元素超出範圍");
}
}
8.1. 使用 () 處理數組
最後,我們可以通過使用 () 方法來檢查數組是否為空,並且至少包含一個元素:
public void repair(String[] repairParts) {
Assert.notEmpty(
repairParts,
"array of repairParts mustn't be empty");
// ...
}8.2. noNullElements()
我們可以通過使用 noNullElements() 方法來驗證數組中是否包含 null 元素:
public void repairWithNoNull(String[] repairParts) {
Assert.noNullElements(
repairParts,
"array of repairParts mustn't contain null elements");
// ...
}請注意,只要數組不包含任何null元素,即使數組為空,檢查仍然會通過。
9. 結論
在本文中,我們探討了 <em >Assert</em> 類。該類在 Spring 框架中被廣泛使用,但我們可以利用它編寫出更健壯和更具表現力的代碼。