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); // 也是輸出地址與上面的地址是一樣的
}
}