一、static關鍵字
1.1、static關鍵字
靜態:static
用法:是一個修飾符,用于修飾成員(成員變量,成員函數)
static 修飾的內容,所有對象共享
當成員被靜態修飾后,就多了一個調用方式,除了可以被對象調用外,還可以被類名.靜態成員
package com.day06;/** * 人類 * @author Administrator *靜態:static *用法:是一個修飾符,用于修飾成員(成員變量,成員函數) *static 修飾的內容,所有對象共享 *當成員被靜態修飾后,就多了一個調用方式,除了可以被對象調用外, *還可以被類名.靜態成員 */public class Person { //屬性 static String country="CN"; String name; public void show(){ System.out.PRintln(this.name+" "+this.country); } public static void main(String[] args) { //多個對象使用同一個屬性國家 Person p=new Person(); Person p1=new Person(); p.name="張三"; p1.name="李四"; p.show(); p1.show(); System.out.println(Person.country); //類名.靜態成員變量 }}
特點:
1.隨著類的加載而加載--也就是:靜態會隨著類的消失而消失,它的生命周期最長。
2.優先于對象存在---
靜態是先存在,對象是后存在。
3.被所有對象共享
4.可以直接被類名所調用
1.2、實例變量和類變量的區別
1.存放位置
類變量隨著類的加載而加載存在方法區中。
實例變量隨著對象的建立而存在于堆內存中。
2.生命周期
類變量生命周期最長,隨著類的消失而消失
實例變量生命周期隨著對象的消失而消失
1.3、使用注意事項
靜態方法只能訪問靜態成員(靜態成員和靜態方法)
非靜態方法既可以訪問靜態也可以訪問非靜態
靜態方法中不可以定義this. super關鍵字
因為靜態優先于對象存在,所以靜態中不可以出現this
主函數是靜態的
靜態有利有弊
利處:對對象共享數據進行單獨空間的存儲,節省內存空間,沒有必要每個對象都存儲一份
可以直接被類名調用。
弊端:生命周期過長
訪問出現局限性。(靜態雖好,只能訪問靜態。)
1.4、主函數是靜態的
主 函數:是一個特殊的函數,作為程序的入口,可以被JVM調用
定義:
public :代表差該該函數訪問權限是最大的
static:代表主函數隨著類的加載就已經存在了。
void:主函數沒有具體的返回值。
main():不是關鍵字,但是是一個特殊的單詞,可以被JVM識別。
函數的參數:String[] args--是一個數組,數組中的元素是字符串,字符串類型的數組
主函數是固定格式的,JVM識別。
args:arguments
JVM在調用主函數時,傳入的是new String[0]
package com.day06;public class MainTest { public static void main(String[] args) { //遍歷主函數 for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } }} package com.day06;public class MainDemo { public static void main(String[] args) { String [] arr={"張三","李四","王五","趙六","錢七"}; MainTest.main(arr); }}
結果:
張三
李四
王五
趙六
錢七
1.5、什么時候使用靜態
2個方面:
靜態修飾的內容有成員變量和函數
什么時候定義靜態變量?
當對象在出現共享數據時,該數據被static修飾
對象中的特有數據要定義成非靜態,存在于堆內存,對象內部
什么時候定義靜態函數
當功能內部沒有訪問到非靜態數據(對象的特有數據)
那么該 功能可以定義成靜態
1.6、靜態工具類
package com.day06;/** * 建立一個用于操作數組的工具類, 其中包含著常見的對數組操作的函數, 如:最值,排序等。 * * @author Denny * @version v1.0 */public class ArrayTool { /** * 為了不讓外界創建對象,將構造方法私有化 * @author Denny * * @version v1.0 */ private ArrayTool() { } /** * 獲取整型數組的最大值 * * @param arr * 接收一個元素為int 類型的數組 * @Return 該數組的最大的元素值 */ public static int getMax(int[] arr) { int maxIndex = 0; for (int x = 1; x < arr.length; x++) { if (arr[x] > arr[maxIndex]) maxIndex = x; } return arr[maxIndex]; } /** * 對數組進行選擇排序 * * @param arr * 接收一個元素為int 的數組 */ public static void selectSort(int[] arr) { for (int x = 0; x < arr.length - 1; x++) { for (int y = x + 1; y < arr.length; y++) { if (arr[x] > arr[y]) swap(arr, x, y); } } } // 用于給數組進行元素的位置置換。 private static void swap(int[] arr, int a, int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } /** * 獲取指定的元素在指定數組中的索引 * * @param arr * 接收一個元素為int 類型的數組 * @param key * 要找的元素 * @return 返回該元素第一次出現的位置,如果不存在則返回 -1 */ public static int getIndex(int[] arr, int key) { for (int x = 0; x < arr.length; x++) { if (arr[x] == key) return x; } return -1; }
/** * 將int數組轉換成字符串,格式是:[e1,e2,...] * * @param arr * 接收一個元素為int類型的數組 * @return 返回該數組的字符串表現形式 */ public static String arrayToString(int[] arr) { String str = "["; for (int x = 0; x < arr.length; x++) { if (x != arr.length - 1) str = str + arr[x] + ","; else str = str + arr[x] + "]"; } return str; }}
使用類名.靜態方法
二、靜態代碼塊
2.1、靜態代碼塊
static{
代碼塊;
}
package com.day06;/** * 靜態代碼塊 * * @author Denny static{ 靜態代碼塊中的語句 } * 特點:隨著類的加載而執行, 只執行一次 用于給類進行初始化 * 并優先于主函數 */class StaticDemo { static { System.out.println("static code A"); }}
public class StaticCode{ static { System.out.println("static code B"); } static { System.out.println("static code C"); } public static void main(String[] args) { //2個匿名對象 new StaticDemo(); new StaticCode(); }}
結果:
static code B
static code C
static code A
只執行一次就不在執行了
三、對象初始化過程
3.1、初始化過程
package com.day06;/** * 靜態代碼塊 * * @author Denny * static{ 靜態代碼塊中的語句 } * 特點:隨著類的加載而執行, 只執行一次 用于給類進行初始化 并優先于主函數 */public class StaticCode { int num=9; public StaticCode() { System.out.println("static code A"); } static { System.out.println("static code B"); } { System.out.println("con code C "+this.num); } public StaticCode(int num) { System.out.println("con code D"); } public static void show(){ System.out.println("E"); } public static void main(String[] args) { new StaticCode(4); }}
結果:
static code B
con code C 9
con code D
四、對象調用成員過程
4.1、初始化過程
1.因為new 用到了類.class,所以會先找到類.class
2.執行該類中的static代碼塊,如果有的話,給類.class進行初始化
3.堆內存中開辟空間,分配內存地址,
4.在堆內存中建立對象的特有屬性,并默認初化成員變量
5.對對象進行顯示初始化
6.對對象進行構造代碼塊初始化
7.對對象進行對應的構造函數初始化。
8.將內存地址賦給內存中的對象變量
五、單例模式
5.1、餓漢式
package com.day06;/** * 餓漢式 * @author denny * */public class SingleDemo { private String name; private int age; private static SingleDemo singleDemo=new SingleDemo(); //私有 構造方法 private SingleDemo(){ } //提供公有的訪問 public static SingleDemo getNewIntance(){ return singleDemo; } public static void main(String[] args) { SingleDemo s1=SingleDemo.getNewIntance(); SingleDemo s2=SingleDemo.getNewIntance(); System.out.println(s1==s2); }}
結果:true
5.2、懶漢式
package com.day06;/** * 餓漢式 * @author denny * */public class SingleDemo2 { private String name; private int age; private static SingleDemo2 singleDemo2; //私有 構造方法 private SingleDemo2(){ } //提供公有的訪問 public static SingleDemo2 getNewIntance(){ if(singleDemo2==null){ singleDemo2=new SingleDemo2(); } return singleDemo2; } public static void main(String[] args) { SingleDemo2 s1=SingleDemo2.getNewIntance(); SingleDemo2 s2=SingleDemo2.getNewIntance(); System.out.println(s1==s2); }}
結果:true
新聞熱點
疑難解答