李興華Java8筆記13:this關鍵字詳解

this有一個核心概念:指的是當前對象。Java裏面可以實現對類屬性的調用、類方法的調用、表示當前對象。接下來一一介紹:

1.調用屬性

首先看一個之前寫過的很簡單的代碼:

class Book{
	private String title;
	private Double price;

	public Book(String t, Double p){
		title = t;
		price = p;
	}

	public void getInfo(){
		System.out.println("書名:"+title+",價格:"+price);
	}
}
public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java開發",89.2);
		books.getInfo(); //輸出:書名:Java開發,價格:89.2
	}
} 

在構造方法中,我們設置書名和價格的參數設置爲了t、p。但是這種命名方法並不符合規範,我們想將形參設置爲title、price,於是有了下面的改進:

class Book{
	private String title;
	private Double price;

	public Book(String title, Double price){
		title = t;
		price = p;
	}

	public void getInfo(){
		System.out.println("書名:"+title+",價格:"+price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java開發",89.2);
		books.getInfo();// 輸出:書名:null,價格:null
	}
} 

但是編譯運行之後,我們什麼也沒有得到。這是因爲變量有一個作用域的概念,上面的Book構造方法中有一個title、Book 類中同樣也有一個成員屬性title,但是構造方法中的title的優先級比較高。因此當我們用title = title 的時候,前面的title並不是類中的屬性title,那怎樣才能夠在保證參數名和類屬性名一致的情況下,正確的調用到成員屬性並賦值呢?那就是this關鍵字了!:

class Book{
	private String title;
	private Double price;

	public Book(String title, Double price){
		this.title = title;
		this.price = price;
	}

	public void getInfo(){
		System.out.println("書名:"+this.title+",價格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java開發",89.2);
		books.getInfo(); //輸出:書名:Java開發,價格:89.2
	}
} 

this關鍵字所指向的title就是本類中的成員屬性,因此在以後的開發中,只要是在類中使用成員屬性,我們就用this關鍵字來調用。

2. 調用方法

2.1 調用構造方法

類中的多個構造方法可能存在相互調用的情況。使用的形式就是this(參數,參數)。例子如下,先要求沒生成一個對象,無論是調用的無參構造還是若干參數的構造方法,都要求輸出一個提示語句:新的對象產生。沒用this()的時候我們可以這樣來寫:

class Book{
	private String title;
	private Double price;

	// 無參構造方法
	public Book(){
		System.out.println("新的對象產生");
	}

	// 一個參數的構造方法
	public Book(String title){
		System.out.println("新的對象產生");
		this.title = title; 
	}

	// 兩個參數的構造方法
	public Book(String title, Double price){
		System.out.println("新的對象產生");
		this.title = title;
		this.price = price;
	}

	public void getInfo(){
		System.out.println("書名:"+this.title+",價格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java開發",89.2); //輸出:新的對象產生
		books.getInfo(); 
		//輸出:書名:Java開發,價格:89.2
	}
}

但是這些寫會產生很多的重複代碼,比如System.out.println(“新的對象產生”)、this.title = title;都屬於重複代碼。但是有了this關鍵字就不一樣了,我們可以用this()代表調用無參構造方法,用this(參數)表示調用一個參數的構造方法,一次類推。於是功能相同的改進代碼如下:

class Book{
	private String title;
	private Double price;

	// 無參構造方法
	public Book(){
		System.out.println("新的對象產生");
	}

	// 一個參數的構造方法
	public Book(String title){
		this();
		this.title = title; 
	}

	// 兩個參數的構造方法
	public Book(String title, Double price){
		this(title);
		this.price = price;
	}

	public void getInfo(){
		System.out.println("書名:"+this.title+",價格:"+this.price);
	}
}

public class Hello{
	public static void main(String[] args){
		Book books = new Book("Java開發",89.2); //輸出:新的對象產生
		books.getInfo(); 
		//輸出:書名:Java開發,價格:89.2
	}
}

這樣一來,多個構造方法之間相互調用的重複代碼問題是解決了,但是新的問題油然而生

  • Java規定this(參數)只能放在方法中的第一行,換個位置就會發生錯誤。
  • 構造方法能調用普通方法,但是普通方法無法使用this()調用構造方法。
  • 構造方法相互調用的時候一定要保留調用的出口。

在上面的代碼中,兩參構造方法調用了一參構造方法,一參構造方法調用了無參構造方法,無參構造方法停止了調用。這讓程序有了一個出口,得以讓代碼正常運行。如果我們在無參構造中再次調用兩參構造方法,會出現“構造方法遞歸調用”的錯誤提示。

// 無參構造方法
	public Book(){
        this("Hello",123.0);
		System.out.println("新的對象產生");
	}

	// 一個參數的構造方法
	public Book(String title){
		this();
		this.title = title; 
	}

	// 兩個參數的構造方法
	public Book(String title, Double price){
		this(title);
		this.price = price;
	}


2.2 實例聯繫

定義一個僱員類(員工編號,姓名,工資,部門),在這個類中編寫四個構造方法:

  • 無參構造:編號爲:0、姓名爲:“無名氏”、工資爲:0.0、部門設置:“未定”
  • 單參構造(傳遞編號):姓名爲:“臨時工”、工資爲:800.0、部門設置:“後勤部”
  • 雙參構造(傳遞編號、姓名):工資爲:2000.0、部門設置:“技術部”
  • 四參構造(傳遞編號、姓名、工資、部門)

實現方法一:普通方法:要啥給啥!

class Emp{
	private int number;
	private String name;
	private Double salary;
	private String department;

	// 無參構造
	public Emp(){
		this.number = 0;
		this.name = "無名氏";
		this.salary = 0.0;
		this.department = "未定";
	}

	// 單參構造
	public Emp(int number){
		this.number = number;
		this.name = "臨時工";
		this.salary = 800.0;
		this.department = "後勤部";
	}

	// 雙參構造
	public Emp(int number, String name){
		this.number = number;
		this.name = name;
		this.salary = 2000.0;
		this.department = "技術部";
	}

	// 四參構造
	public Emp(int number, String name, Double salary, String department){
		this.number = number;
		this.name = name;
		this.salary = salary;
		this.department = department;
	}

	public String getInfo(){
		return "編號:"+this.number+",姓名:"+this.name+",工資"+this.salary+",部門:"+this.department;
	}
}

public class Hello{
	public static void main(String[] args){
		Emp emp1 = new Emp(); 
		Emp emp2 = new Emp(1234); 
		Emp emp3 = new Emp(3389,"向東"); 
		Emp emp4 = new Emp(2232,"金津",123.0,"銷售部"); 
		
		System.out.println(emp1.getInfo());
		System.out.println(emp2.getInfo());
		System.out.println(emp3.getInfo());
		System.out.println(emp4.getInfo());
	}
}

// 輸出結果
編號:0,姓名:無名氏,工資0.0,部門:未定
編號:1234,姓名:臨時工,工資800.0,部門:後勤部
編號:3389,姓名:向東,工資2000.0,部門:技術部
編號:2232,姓名:金津,工資123.0,部門:銷售部

上面方法的缺點顯而易見,代碼重複率太高,我們可以用this()方法進行改進:

class Emp{
	private int number;
	private String name;
	private Double salary;
	private String department;

	// 無參構造
	public Emp(){
		this(0,"無名氏",0.0,"未定");
	}

	// 單參構造
	public Emp(int number){
		this(number,"臨時工",800.0,"後勤部");
	}

	// 雙參構造
	public Emp(int number, String name){
		this(number,name,2000.0,"技術部");
	}

	// 四參構造
	public Emp(int number, String name, Double salary, String department){
		this.number = number;
		this.name = name;
		this.salary = salary;
		this.department = department;
	}

	public String getInfo(){
		return "編號:"+this.number+",姓名:"+this.name+",工資"+this.salary+",部門:"+this.department;
	}
}

public class Hello{
	public static void main(String[] args){
		Emp emp1 = new Emp(); 
		Emp emp2 = new Emp(1234); 
		Emp emp3 = new Emp(3389,"向東"); 
		Emp emp4 = new Emp(2232,"金津",123.0,"銷售部"); 
		
		System.out.println(emp1.getInfo());
		System.out.println(emp2.getInfo());
		System.out.println(emp3.getInfo());
		System.out.println(emp4.getInfo());
	}
}

2.3 調用普通方法

普通方法之間的調用可以不加this,但是爲了保證程序的嚴謹性,還是建議加上this.

3. 表示當前對象

this表示當前對象,表示正在調用當前方法的對象。

class Book{
	public Book(){
		System.out.println("this:"+this);
	}
}

public class Hello{
	public static void main(String[] args){
		Book book = new Book(); 	// 輸出當前對象的堆內存地址
		System.out.println(book);	// 也是輸出地址與上面的地址是一樣的
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章