一、前言
java進階篇已經開始了,先從面向對象開始,由于時間原因今天就只更新了static部分,內容上特別詳細,一些特別的注意事項也在反復的提醒大家。
溫馨提示一下,往后的java篇會越來越難,希望大家能夠堅持下去。大家一起努力!!!
二、基礎概念
定義靜態變量
靜態變量使用 static
關鍵字聲明。通常在類級別、方法外部定義,并且在整個類的生命周期內存在一份實例。靜態變量可以是基本數據類型(如 int
、double
等)或引用類型(如對象的引用)。
?訪問靜態變量
靜態變量可以通過類名直接訪問,也可以通過對象實例訪問,但推薦使用類名訪問,因為靜態變量不是對象的一部分。
靜態變量的初始化
靜態變量可以在聲明時初始化,也可以在靜態初始化塊中初始化。靜態初始化塊在類加載時執行,并且僅執行一次。
特點與注意事項
-
類級別共享:靜態變量的值對所有類的實例來說是共享的,它們只有一份拷貝存在于內存中。
-
生命周期:靜態變量隨著類的加載而初始化,而不是隨著對象的創建而初始化。它們存在于整個類的生命周期內,直到程序結束或類被卸載。
-
線程安全:靜態變量在多線程環境下可能存在并發訪問的問題,因此需要考慮線程安全性,可以使用
synchronized
關鍵字或其他并發控制機制來保護靜態變量的訪問。 -
命名規范:通常靜態變量的命名習慣是使用大寫字母和下劃線分隔單詞(例如
MAX_SIZE
),以區分于實例變量。 -
應用場景:靜態變量通常用于表示類的常量(如
Math.PI
)、計數器(記錄類實例創建次數)、單例模式中的實例等場景。
三、static靜態變量
?看上圖可以發現,李四的輸出信息中沒有老師的姓名,那是因為李四并沒有給teacher這個變量賦值。
總所周知,在一個教室中,老師是學生們共有的,所以有沒有一種方法使得所有學生都能有這一屬性呢,答案當然是有的。這就得使用我們的static靜態變量了。
代碼優化:
Student.teacher = "李老師";
Student student = new Student();
student.setName("張三");
student.setAge(18);
student.setGender("男");student.study();
student.show();Student student1 = new Student("李四", 19, "女");
student1.study();
student1.show();
運行結果:
思考一下teacher這一變量并沒有賦值給學生,但是每個學生都有這一屬性。
這就是靜態變量的神奇之處,?
好好的去理解一下這句話。
只要在類中存在了,他就會存在于整個生命周期中。?
靜態變量的值對所有類的實例來說是共享的。
四、static內存圖
圖片出自黑馬程序員
注:靜態變量是隨著類的加載而加載的,優先于對象出現。
注:靜態區的變量是共享的?
?
?五、靜態方法和工具類
幾種常見的工具類
javabeen類
Java Bean 類是Java開發中常見的一種模式,它有助于實現數據的封裝和重用,同時也是構建面向對象程序設計中的基礎組件之一。
使用 Java Bean 類的場景:
- 數據封裝:用于封裝應用程序中的數據,提供簡潔的訪問和修改方式。
- 數據傳輸:用于傳輸數據,例如在客戶端和服務器之間,或者在不同層之間。
- 框架兼容性:許多框架(如Spring等)利用 Java Bean 的約定進行依賴注入和配置管理。
?測試類
在Java中,測試類通常用于編寫和運行單元測試,以驗證程序的各個部分是否按預期工作。這些測試類是獨立的Java類,用于測試應用程序中的其他類或方法的功能和行為。
編寫測試類的基本步驟
導入必要的類和方法:
- 根據選擇的測試框架,導入正確的測試注解和斷言方法。通常,需要導入類似于?
org.junit.jupiter.api.Test
?和?org.junit.jupiter.api.Assertions.*
?這樣的類。
編寫測試方法:
- 使用測試框架提供的注解(如?
@Test
)標記測試方法,以便測試運行器能夠識別它們。- 在方法中編寫測試邏輯,通常包括調用待測試的方法或類,并使用斷言來驗證預期的行為或結果是否正確。
運行測試:
- 在集成開發環境(IDE)中,通常可以通過右鍵單擊測試類并選擇“運行測試”來直接運行單元測試。
- 也可以通過構建工具(如 Maven 或 Gradle)的測試插件來運行測試,或者使用命令行界面運行測試。
工具類?
Java 中的工具類是一種常見的編程實踐,用于封裝一些常用的靜態方法或者提供一些靜態字段,以便在整個應用程序中方便地進行調用和重用。工具類通常不包含狀態,其方法一般是無副作用的,主要用于功能性的操作。
靜態方法:
工具類中的方法通常是靜態的,可以直接通過類名調用,無需實例化對象。
私有構造函數:
通常會將工具類的構造函數聲明為私有,以防止被實例化。因為工具類主要是為了提供靜態方法,而不是創建對象。
常用的靜態方法:
工具類可以包含各種常用的靜態方法,例如字符串處理、日期操作、數學計算等。
無狀態:
工具類通常不包含成員變量,也不維護狀態,這樣可以確保其方法的純粹性,避免副作用。
實用性:
工具類主要用于封裝一些通用的操作,提高代碼的復用性和可維護性。在大型項目中特別有用,可以減少代碼重復。
?定義數組工具類
代碼實現:?
/*** 將整數數組轉換為字符串表示形式。* 該方法通過StringBuilder構建數組的字符串表示,以避免使用+操作符連接字符串時的性能問題。* 它遍歷數組,并將每個元素添加到StringBuilder中,除了最后一個元素之外,每個元素后面都跟上一個逗號。* 最后,方法返回StringBuilder的字符串形式,該字符串以方括號包圍數組元素。** @param arr 整數數組,要轉換為字符串表示的數組。* @return 字符串表示的數組,格式為"[元素1, 元素2, ..., 元素n]"。*/public static String printArray(int[] arr){// 初始化StringBuilder以構建數組的字符串表示。StringBuilder sb = new StringBuilder();// 開始構建字符串,先添加左方括號。sb.append("[");// 遍歷數組中的每個元素。for (int i = 0; i < arr.length; i++) {// 如果當前元素是最后一個元素,就不添加逗號。if (i == arr.length - 1){sb.append(arr[i]);}else {// 對于其他元素,在其后面添加逗號。sb.append(arr[i]).append(",");}}// 完成構建字符串,添加右方括號。sb.append("]");// 返回構建好的字符串表示的數組。return sb.toString();}
/*** 計算數組的平均值。* * @param arr2 一個double類型的數組,用于計算平均值。* @return 返回數組所有元素的平均值。*/public static double getAverage(double[] arr2){double sum = 0; // 初始化累加和為0// 遍歷數組,累加數組中的每個元素for (int i = 0; i < arr2.length; i++) {sum += arr2[i];}// 返回累加和除以數組長度得到的平均值return sum / arr2.length;}
?結果展示:
定義學生工具類
?代碼實現:
/*** StudentUtil類是一個工具類,用于學生信息的操作。* 該類被設計為不可實例化,通過提供靜態方法來服務。*/
private StudentUtil(){}/*** 獲取學生列表中最大的年齡。* * @param list 一個ArrayList類型的學生列表,不能為空。* @return 返回學生列表中的最大年齡。* * 注意:該方法假設列表至少有一個學生,沒有進行空列表的檢查。*/
public static int getMaxAge(ArrayList<Student>list){/* 初始化最大年齡為列表第一個學生的年齡 */int maxAge = list.getFirst().getAge();/* 遍歷學生列表,尋找最大年齡 */for (Student student : list) {/* 如果當前學生的年齡大于已知的最大年齡,則更新最大年齡 */if (student.getAge() > maxAge) maxAge = student.getAge();}/* 返回找到的最大年齡 */return maxAge;
}
結果展示:
六、static注意事項和使用場景
靜態字段:
靜態字段屬于類而不是實例。這意味著所有實例共享同一個靜態字段的值。應謹慎使用靜態字段,因為它們的狀態是全局的,并可能導致并發訪問問題。
靜態方法:
靜態方法可以直接通過類名調用,無需實例化對象。通常用于實現工具類、工廠方法或者在沒有實例化對象時執行某些操作的情況。靜態方法不能訪問非靜態方法或者實例變量,因為它們沒有隱式的?
this
?引用。
靜態塊:
靜態塊用?
static { ... }
?來聲明,它在類加載時執行,并且僅執行一次。通常用于初始化靜態字段或執行靜態方法。
靜態類:
如果類被聲明為?
static
,那么它通常是一個內部類,表明它不需要外部類的實例即可被實例化。靜態內部類不能直接訪問非靜態的外部類成員。
注意事項:
- 線程安全性:靜態字段和方法是類級別的,可能會影響多個實例或線程。確保在多線程環境下使用時考慮到線程安全性。
- 單例模式:靜態方法和塊常用于實現單例模式。確保單例的唯一性和線程安全性是使用靜態的重要考慮因素。
- 依賴注入:靜態方法或字段不適合用于依賴注入,因為它們導致代碼緊耦合,并使得單元測試變得困難。
- 靜態導入:
- 使用?
import static
?可以導入靜態方法和字段,使得在使用時可以不通過類名而直接訪問。這在某些情況下可以提高代碼的可讀性,但也要避免濫用,以免降低代碼的可維護性。