Java課堂篇4_關鍵字this、static的理解

Linus_xs發表於2020-10-29

寫在前面

Java課堂篇3_物件型別下的“==“和equals()、字串常量池、(-128-127)int型別裝箱Integer大整型常量池、關於static關鍵字 簡單記錄了static關鍵字和靜態常量池的的關係

下面主要記錄一下this指標和static關鍵字修飾的類沒有this指標等情況


目錄

  • this關鍵字
  • static關鍵字

開始

先來一個小栗子

  • Monkey類
import java.time.ZoneOffset;

/**
 * @author 司超龍
 *
 */
public class Monkey {
	//靜態成員變數
	private static String zoo = "花果山";
	//普通成員變數
	private String name;
	private int age;
	private double weight;
	
	public Monkey() {
		// TODO Auto-generated constructor stub
	}
	
	
	public Monkey(String name, int age, double weight) {
		super();
		this.name = name;
		this.age = age;
		this.weight = weight;
	}


	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
	public double getWeight() {
		return weight;
	}
	public static String getZoo() {
		return zoo;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	public static void setZoo(String zoo) {
		Monkey.zoo = zoo;
	}
	
	//普通成員方法
	public void run(String name) {
		System.out.println(this.name +  " 跑起來了~~");
	}
	public void eat() {
		System.out.println(this.name + " 正在吃香蕉~~");
	}
	//靜態成員方法
	public static void sleep() {
		System.out.println("我睡著了");
	}
	/**
	 * 下面程式碼報錯
	 * @param name
	 */
	/*
	public static execrise(String name) {
		System.out.println(this.name + " 在鍛鍊!!是一個自律猴~");
	}
	*/

}

  • 測試Main類

public class ThisZhiZhen {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//建立猴子a
		Monkey aMonkey = new Monkey("xiaosi",19,50);
		//建立猴子b
		Monkey bMonkey = new Monkey("si",20,51);
		
		//呼叫普通無參成員方法
		aMonkey.eat();
		bMonkey.eat();
		System.out.println("===========");
		
		//呼叫有參普通成員方法
		aMonkey.run(aMonkey.getName());
		bMonkey.run(bMonkey.getName());
		System.out.println("============");
		
		//分別使用類名、物件名,獲取靜態成員變數
		System.out.println(Monkey.getZoo());
		
		//使用物件名獲取靜態成員變數,雖然不算錯,但是不建議
		System.out.println(aMonkey.getZoo());
		System.out.println(bMonkey.getZoo());
		
		//使用某一個物件名,修改靜態成員變數,不能算錯,但是不建議
		aMonkey.setZoo("開封動物園");
		
		//再次列印,發現全部改變
		System.out.println(Monkey.getZoo());
		System.out.println(aMonkey.getZoo());
		System.out.println(bMonkey.getZoo());
		System.out.println("==============");
		
		//使用物件名,呼叫靜態成員方法,不能算錯,但是不建議
		aMonkey.sleep();
		bMonkey.sleep();
		System.out.println("============");
		
		

	}

}

在這裡插入圖片描述

由上面的程式碼我們可以看出來:

  • 物件名、類名都可以呼叫 靜態無參成員方法,獲取靜態成員變數、設定靜態成員變數(只不過是物件名呼叫不太建議,因為上篇部落格也提到,static修飾的方法、屬性,就屬於這個類物件的了,不在屬於例項化物件個體得了)
  • 物件名可以呼叫 無參、有參 普通成員方法,對於有參的成員方法呼叫,需要傳入例項化物件的引數

我們都知道,每個例項化物件都有 屬於 自己的 普通成員變數,這很容易理解,但是 那些普通的成員 方法呢?

是每個物件都有屬於自己的一份呢,還是隻有 類中的單獨一份,或者這樣說,每個例項物件堆區記憶體空間,是否都包含類內的普通成員方法呢?

答案當然是 只有一份,所有的例項物件呼叫的都是類內的方法

那麼問題又來了,既然多個物件呼叫的是類內的同一個方法,那麼怎麼區分是哪個物件呼叫的呢?、

這就是this指標的功能了


一、this關鍵字

this關鍵字,也稱為了this指標,就是指向例項化物件堆區的地址,類似的還有super關鍵字等

this指標可以理解為 就是 當前 使用者 的 一個 別名

因為例項物件可以有很多,理想狀態每個例項物件都有相同的方法(技能),屬性可能不太相同,因此只需要 把 個性的 特徵單獨儲存,對於一致的方法(技能)就不需要在浪費空間,共享出來共所有例項物件需要時呼叫即可(封裝)

這些共享的方法,就需根據this區分不同的呼叫者,看下面程式碼

public void eat() {
		System.out.println(name + " 正在吃香蕉~~");
	}
	
	/*
	 * 和上面效果相同
	public void eat() {
		System.out.println(this.name + " 正在吃香蕉~~");
	}
	*/
/*
	 * public void run( String name) {
		 System.out.println(this.name +  " 跑起來了~~");
		 和下面效果相同
	   }
	 
	 */
	
	public void run( String name) {
		System.out.println(name +  " 跑起來了~~");
	}

因此對於非靜態成員方法,在例項物件呼叫他們的時候,都會有一個預設的引數this,只不過我們有時看不見他們

但是,編譯器一定可以看見他們

public void eat(this) {
		System.out.println(this.name + " 正在吃香蕉~~");
	}


//呼叫普通無參成員方法
		aMonkey.eat();
		bMonkey.eat();
		/*
		 * 相當於
		 * eat(aMonkey)
		 * eat(bMonkey)
		 * 
		 */


public void run( String name) {
		System.out.println(name +  " 跑起來了~~");
	}
	/*
	 * 	public void run(this, String name) {
			System.out.println(this.name +  " 跑起來了~~");
		}
	 */


//呼叫有參普通成員方法
		aMonkey.run(aMonkey.getName());
		bMonkey.run(bMonkey.getName());
		
		/*
		 * run(this,this.getName)
		 * run(aMonkey,aMonkey.getName());
		 * run(bMonkey,bMonkey.getName());
		 * 
		 */

關於this引數,預設被編譯器預設

對於static修飾的成員變數、成員方法有沒有這個this指標呢?

答案是沒有


二、static關鍵字

在這裡插入圖片描述

更多參考:菜鳥教程

也就是說

  • 靜態成員變數在記憶體中只有一份,可以通過物件名訪問,但是不建議,一般通過類名設定,訪問
  • 靜態成員方法沒有this指標,不能使用類的非靜態變數,因為類的非靜態變數值 是屬於 例項物件的,值是不確定的
/**
	 * 報錯!!
	 * @param name
	 */
	
	public static execrise(String name) {
		System.out.println(this.name + " 在鍛鍊!!是一個自律猴~");
	}
/*

	execrise()
	
	execrise(aMonkey)//引數多了好辦,不用傳下去,直接丟棄
	execrise(aMonkey)//引數多了好辦,不用傳下去,直接丟棄
	
	

*/
	

相關文章