1. 程式人生 > >[Java教程 29] static關鍵字詳解

[Java教程 29] static關鍵字詳解

static關鍵字的引入

/**
	定義一個人類
	
	姓名和年齡都是變化的,這個我能接受,因為每個人的性別和年齡都是不同的。
	但是,我們現在選取的幾個人都是中國人,他們的國籍都是一樣的。
	一樣的國籍,我每次建立物件,在堆記憶體中都要開闢這樣的空間,
	浪費了空間。
	怎麼辦?
	針對多個物件有共同的成員變數值的時候,java就提供了一個關鍵字來修飾:static
*/
class Person{
	//姓名
	String name;
	//年齡
	int age;
	//國籍
	//String country;
	static String country;
	
	public Person(){}
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	public Person(String name,int age,String country){
		this.name = name;
		this.age = age;
		this.country = country;
	}
	
	public void show(){
		System.out.println("姓名:"+this.name+",年齡:"+this.age+",國籍"+this.country);
	}
}

public class PersonDemo{
	public static void main(String[] args){
		//建立物件1
		Person p1 = new Person("呆萌鍾",23,"中國");
		p1.show();
		//建立物件2
		//Person p2 = new Person("迪麗熱巴",24,"中國");
		//p2.show();
		Person p2 = new Person("迪麗熱巴",24);
		p2.show();
		//建立物件3
		//Person p3 = new Person("鳳姐",31,"中國");
		//p3.show();
		Person p3 = new Person("鳳姐",31);
		p3.show();
		
		p3.country = "美國";
		p3.show();
		
		p1.sho();
		p2.show();
	}
}	

static關鍵字

可以修飾成員變數和成員方法

static關鍵字特點

  • 隨著類的載入而載入
  • 優先於物件存在
  • 被類的所有物件共享
    • 這也是我們判斷是否使用靜態關鍵字的條件
  • 我們可以通過類名呼叫
/**
	static的特點:(它可以修飾成員變數,也可以修飾成員方法)
		A:隨著類的載入而載入
			回想main方法
		B:優先於物件存在
		C:被類的所有物件共享
			舉例:
				一個班的學生應該共用一個班級編號。
				什麼時候該用靜態?
				如果某個成員變數是被所有物件共享的,那麼它就應該定義為靜態的。
		D:可以通過類名呼叫
			其實它本身也可以通過物件呼叫
			推薦使用類名呼叫
			靜態修飾的內容一般我們稱其為:與類相關的,類成員。
*/
class Student{
	//非靜態變數
	int num = 10;
	//靜態變數
	static int num2 = 20;
}

public class StudentDemo{
	public static void main(String[] args){
		Student s = new Student();
		System.out.println(s.num);
		
		System.out.println(Student.num2);
		System.out.println(s.num);
	}
}

static關鍵字注意事項

  • 在靜態方法中是沒有this關鍵字的
  • 靜態方法只能訪問靜態的成員變數和靜態的成員方法
/**
	static關鍵字注意事項:
		A:在靜態方法中是沒有this關鍵字的
			如何理解呢?
				靜態是隨著類的載入而載入,this是隨著物件的建立而存在。
				靜態比物件先存在。
		B:靜態方法只能訪問靜態成員變數和靜態成員方法
			靜態方法:
				成員變數:只能訪問靜態變數
				成員方法:只能訪問靜態成員方法
			非靜態方法:
				成員變數:可以是靜態的,也可以是非靜態的
				成員方法:可以是靜態的成員方法,也可是非靜態的成員方法
			簡單記:
				靜態只能訪問靜態
*/
class Teacher{
	public int num = 10;
	public static int num2 = 20;
	
	public void show(){
		System.out.println(num);//隱含的告訴你訪問的是成員變數
		System.out.println(this.num);//明確的告訴你訪問的是成員變數
		
		//function();
		//function2();
	}
	
	public static void method(){
		//無法從靜態上下文中引用非靜態變數num
		//System.out.println(num);
		System.out.println(num2);
		//無法從靜態上下文中引用非靜態方法function()
		//function();
		function2();
	}
	
	public void function(){
		
	}
	
	public static void function2(){
		
	}
}

public class TeacherDemo{
	public static void main(String[] args){
		//建立物件
		Teacher t = new Teacher();
		t.show();
		System.out.println("--------------------");
		t.method();
	}
}

靜態變數和成員變數的區別

所屬不同

  • 靜態變數屬於類,所以也稱為類變數
  • 成員變數屬於物件,所以也稱為例項變數(物件變數)

記憶體中位置不同

  • 靜態變數儲存於方法區的靜態區
  • 成員變數儲存於堆記憶體

記憶體出現時間不同

  • 靜態變數隨著類的載入而載入,隨著類的消失而消失
  • 成員變數隨著物件的建立而存在,隨著物件的消失而消失

呼叫不同

  • 靜態變數可以通過類名呼叫,也可以通過物件呼叫
  • 成員變數只能通過物件名呼叫

main方法是靜態的

public static void main(String[] args){}

  • public被jvm呼叫,訪問許可權足夠大
  • static被jvm呼叫,不用建立物件,直接類名訪問
  • void被jvm呼叫,不需要給jvm返回值
  • main一個通用的名字,雖然不是關鍵字,但是被jvm識別
  • String[] args以前用於接收鍵盤錄入的
/**
	main方法的格式講解:
		public static void main(String[] args){}
		
		public:公共的,訪問許可權是最大的。由於main方法是被jvm呼叫,所以許可權要夠大
		static:靜態的,不需要建立物件,通過類名就可以。方便jvm呼叫。
		void:方法的返回值是返回給呼叫者的,而main方法是被jvm呼叫,返回內容給jvm沒有意義。
		main:是一個常見的方法入口,很多語言都是用main作為方法入口的。
		String[] args:這是一個字串陣列。
					有什麼用?怎麼給值?
					這個東西早期是為了接收鍵盤錄入的資料的。(因為jdk5之前沒有Scanner)
					格式:
						java 類名 hello world java
*/
public class MainDemo{
	public static void main(String[] args){
		//System.out.println(args);//地址值
		//System.out.println(args.length);//0
		//System.out.println(args[0]);//ArrayIndexOutOfBoundsException
		
		//接收資料後
		System.out.println(args);
		System.out.println(args.length);
		//System.out.println(args[0]);
		for(int x=0;x<args.length;x++){
			System.out.println(args[x]);
		}
	}
}