智漁課堂官方免費教程十:Java基礎之關鍵字static和this

關鍵字static

static:靜態的,用於修飾類的成員;
被static修飾的成員,在字節碼文件(.class文件)被類加載器(Classloader)從硬盤加載到內存中時,就被在內存中創建。沒有被static修飾的成員在使用關鍵字new創建對象後才被創建
被static修飾的成員,一個類只有一份,不屬於某個對象,而且會常駐內存;
例如:地球屬於全人類,而不屬於某一個人。
靜態屬性的調用:類名.屬性名;
靜態方法的調用:類名.方法名();
靜態塊語法格式:static{ //代碼 };class文件被加載的時候執行一次
在靜態方法或靜態塊中直接調用類的屬性,這個屬性也必須是靜態的
當靜態的屬性和靜態塊或靜態方法在一個類中時,可以直接使用屬性名來訪問屬性
實例:
/**
 * 演示關鍵字static的使用
 * @author 學霸聯盟 - 趙燦
 */
public class StaticDemo {
	// 聲明一個靜態的屬性name,並賦值爲“張三”
	static String name = "張三";
	// 聲明一個非靜態的屬性age,並賦值爲1
	int age = 18;

	// 聲明一個靜態方法
	static void staticMethod1(){
		System.out.println("靜態方法staticMethod1");
		/*
		 * 這裏可以直接使用靜態成員name和staticMethod2
		 * 但是想要使用非靜態成員age、method1和method2
		 * 就必須創建對象,再使用對象調用非靜態的成員
		 */
		staticMethod2();
		System.out.println("靜態的屬性name:" + name);
	}
	// 聲明一個靜態方法
	static void staticMethod2(){
		//這裏可以直接調用靜態成員
		System.out.println("靜態方法staticMethod2");
	}
	// 聲明一個非靜態方法
	void method1(){
		System.out.println("非靜態方法method1");
		//這裏可以直接使用靜態成員和非靜態成員
		method2();
		// 普通屬性必須使用對象調用
		System.out.println("非靜態的屬性age:" + age);
	}
	// 聲明一個非靜態方法
	void method2(){
		System.out.println("非靜態方法method2");
	}
	/*
	 * main方法是靜態方法
	 * 靜態方法中可以直接使用本類靜態成員,也可以通過類名調用靜態成員
	 * 但使用非靜態成員時,無論是本來還是其他類,都要先創建對象
	 * 再通過對象去調用非靜態的成員
	 */
	public static void main(String[] args) {
		// 靜態的成員可以直接使用類名.成員的方式調用,無需創建對象再調用
		StaticDemo.staticMethod1();
		// 創建一個Person類的對象p
		StaticDemo sd = new StaticDemo();
		sd.method1();
	}
}
運行結果:
靜態方法staticMethod1
靜態方法staticMethod2
靜態的屬性name:張三
非靜態方法method1
非靜態方法method2
非靜態的屬性age:18
實例:
/**
 * 演示普通代碼塊和靜態代碼塊
 * @author 學霸聯盟 - 趙燦
 */
public class CodeBlockDemo {
	static int si = 1;
	int i = 1;
	//靜態塊:只會再該類的class文件被加載時執行一次
	static{
		//靜態塊中可以直接使用靜態成員,但不能直接使用非靜態成員
		System.out.println("靜態塊被執行");
	}
	//非靜態代碼塊:創建一個對象,就會被執行一次
	{
		//非靜態塊中可以直接使用靜態成員,也可以直接使用非靜態成員
		System.out.println("普通代碼塊被執行");
	}
	public static void main(String[] args) {
		//在main方法開始之前,靜態塊就已經執行
		System.out.println("----- main方法開始 -----");
		//未創建當前類的對象之前,就執行了靜態塊
		System.out.println("si = " + si);

		//普通代碼塊,創建對象時被執行
		System.out.println("----- 創建對象開始 -----");
		/*
		 * 創建一個對象時
		 */
		CodeBlockDemo cbd1 = new CodeBlockDemo();
		//輸出結果:cbd1.si = 1 , cbd1.i = 1
		System.out.println("cbd1.si = " + cbd1.si + " , cbd1.i = " + cbd1.i);

		//對靜態屬性si和非靜態屬性i都進行修改
		cbd1.si = 10;
		cbd1.i = 10;
		System.out.println("----- 再次創建對象開始 -----");
		CodeBlockDemo cbd2 = new CodeBlockDemo();
		//輸出結果:cbd1.si = 10 , i = 10
		System.out.println("cbd1.si = " + cbd1.si + " , i = " + cbd1.i);
		//輸出結果:cbd2.si = 10 , i = 1
		System.out.println("cbd2.si = " + cbd2.si + " , i = " + cbd2.i);
	}
}
運行結果:
靜態塊被執行
----- main方法開始 -----
si = 1
----- 創建對象開始 -----
普通代碼塊被執行
cbd1.si = 1 , cbd1.i = 1
----- 再次創建對象開始 -----
普通代碼塊被執行
cbd1.si = 10 , i = 10
cbd2.si = 10 , i = 1
由結果可以看出,靜態的屬性si一個類只有一份,兩個對象cdb1和cdb2共同擁有這一份,任何一個對象對靜態的屬性進行修改,其他對象訪問時也會隨之改變。而非靜態的屬性i,則是每個對象各有一份,所以修改某一個對象的非靜態屬性,其他對象不會隨之改變

關鍵字this

一個指向自身的引用(變量),他在哪個對象中,他的值就是哪個對象的地址。
實例:
/**
 * 演示關鍵字this的使用
 * @author 學霸聯盟 - 趙燦
 */
public class ThisDemo {
	// 聲明一個變量a並賦值爲123
	public int a = 123;
	/*
	 * 聲明一個變量b並賦值爲變量a的值,所以變量b的值也是123
	 * 創建一個對象執行一次
	 */
	public int b = this.a;

	// 聲明一個沒有返回值,沒有參數的方法print
	public void print() {
		// 聲明一個局部變量a,局部變量和成員變量可以重名
		int a = 456;
		// 變量a前沒用關鍵字this,代表使用的是局部變量a;輸出的值是456
		System.out.println(a);
		// 變量a前使用了關鍵字this,代表使用的是成員變量a;輸出的值是123
		System.out.println(this.a);
		// 由於沒有局部變量和成員變量b重名,所以前面的this可以省略
		System.out.println(b);
		System.out.println("this的地址:" + this);
	}

	//靜態的main方法
	public static void main(String[] args) {
		// new語句執行完,其中的變量a和b都有了值是123
		ThisDemo td1 = new ThisDemo();
		// 給對象td1的屬性a賦值爲789
		td1.a = 789;
		// 調用對象td1的print方法,此時ThisDemo類中使用的this都和td1中存儲的地址相同
		td1.print();
		System.out.println("td1的地址:" + td1);
		// 創建對象td2
		ThisDemo td2 = new ThisDemo();
		// 使用對象td2調用print方法,此時ThisDemo類中使用的this都和td2中存的地址相同
		td2.print();
		System.out.println("td2的地址:" + td2);
	}
}
輸出結果:
456
789
123
this的地址:cls.keyword.ThisDemo@659e0bfd
td1的地址:cls.keyword.ThisDemo@659e0bfd
456
123
123
this的地址:cls.keyword.ThisDemo@2a139a55
td2的地址:cls.keyword.ThisDemo@2a139a55

小結:

1、不能用在static修飾的成員中,因爲this代表的是對象的引用
2、如果在非靜態的方法或非靜態的代碼塊中,沒有局部變量和屬性(成員變量)重名,this可以省略;否則,必須使用 this.屬性的方式來訪問類的屬性
3、調用本類的其他構造方法:this( [參數列表] )
使用關鍵字this調用構造方法時,只能在構造方法中調用,而且調用時必須寫在構造方法中的第一行;構造方法不能自己調用自己,不能相互調用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章