1. 程式人生 > >Java中this關鍵字 & static關鍵字

Java中this關鍵字 & static關鍵字

1. this關鍵字

this關鍵字主要有以下三個方面的用途:

  • this呼叫本類屬性
  • this呼叫本類方法
  • this表示當前物件

1.1 this呼叫本類屬性

先看一段程式碼:

class Person{
    private String name;
    private int age;

    public Person(String name, int age)
    {
        name = name;
        age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:"
+ name + " 年齡:" + age; } } public class Test{ public static void main(String[] args){ Person per = new Person("張三", 20); System.out.println(per.getPersonInfo()); } }

執行結果如下: 在這裡插入圖片描述 大家會發現,明明例項化物件時,Person(“張三”, 20); 但是得出的結果卻是不是我們想要的結果。我們再看構造方法有了下面的程式碼:

        name = name;
        age =
age;

通過以上程式碼我們可以發現,當引數中屬性同名是,類中屬性無法被正確賦值。此時我們加上this關鍵字便可正確給物件屬性賦值。

        this.name = name;
        this.age = age;

只要在類中方法訪問類中屬性,一定要加上this關鍵字。

1.2 this呼叫本類方法

this呼叫本類方法有一下兩種情況:

  1. 呼叫普通方法
this.方法名稱(引數);
  1. 呼叫構造方法
this.引數;

1.2.1 this呼叫普通方法

舉例:

class Person{
    private String name;
    private int
age; public Person(String name, int age) { this.name = name; this.age = age; this.print();//呼叫普通方法 } public String getPersonInfo() { return "姓名:" + name + " 年齡:" + age; } public void print() { System.out.println("*******************"); } } public class Test{ public static void main(String[] args){ Person per = new Person("張三", 20); System.out.println(per.getPersonInfo()); } }

執行結果如下: 在這裡插入圖片描述 雖然呼叫本類普通方法不需要加上this也可以正常呼叫。但強烈建議加上,加上this的目的可以區分方法定義的來源(在繼承中有用)

1.2.2 this呼叫構造方法

舉例:先觀察構造方法中存在的問題

class Person{
    private String name;
    private int age;

    public Person()
    {
        System.out.println("********產生一個新的Person物件*******");
    }
    public Person(String name)
    {
        System.out.println("********產生一個新的Person物件*******");
        this.name = name;
    }
    public Person(String name, int age)
    {
        System.out.println("********產生一個新的Person物件*******");
        this.name = name;
        this.age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + "  年齡:" + age;
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        Person per2 = new Person("李四");
        Person per3 = new Person("張三", 20);
        System.out.println(per1.getPersonInfo());
        System.out.println(per2.getPersonInfo());
        System.out.println(per3.getPersonInfo());
    }
}

在這裡插入圖片描述 上述程式碼在構造方法中出現了一些程式碼重複問題,想要解決此類問題,就需要用到this. 在Java中,支援構造方法的互相呼叫(this)。 修改程式碼如下:

class Person{
    private String name;
    private int age;

    public Person()
    {
        System.out.println("********產生一個新的Person物件*******");
    }
    public Person(String name)
    {
        this();//呼叫本類無參構造
        this.name = name;
    }

    public Person(String name, int age)
    {
        this();//呼叫本類有一個引數的構造方法
        this.age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + "  年齡:" + age;
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        Person per2 = new Person("李四");
        Person per3 = new Person("張三", 20);
        System.out.println(per1.getPersonInfo());
        System.out.println(per2.getPersonInfo());
        System.out.println(per3.getPersonInfo());
    }
}

執行結果如下: 在這裡插入圖片描述 使用this呼叫構造方法時請注意:

  1. 只能在構造方法中使用this呼叫其他的構造方法,不能再成員方法中使用。
  2. 在構造方法中,使用this呼叫構造方法的語句必須位於第一行,且只能出現一次。下面的寫法時非法的,必須在寫程式碼時注意。
Public Person(String name, int age) {
	this.age = age;
	this(name);	//呼叫有參的構造方法。由於不在第一行,編譯錯誤。
}

執行結果如下: 在這裡插入圖片描述

  1. 不能在一個類的兩個構造方法中使用this互相呼叫,下面的寫法編譯會報錯。
    public Person(){
        this("lisi");//呼叫有參的構造方法
        System.out.println("****無參構造****");
    }
    public Person(String name){
        this(); //呼叫無參的構造方法
        System.out.println("****有參構造****");s
    }

執行結果如下: 在這裡插入圖片描述

1.3 this表示當前物件

舉例:this表示當前物件

class Person{
    public void print(){
        System.out.println("[PRINT]方法:" + this);      
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        System.out.println("[MAIN]方法: " + per1);
        per1.print();
        System.out.println("************************");
        Person per2 = new Person();
        System.out.println("[MAIN]方法: " + per2);
        per2.print();
    }
}

在這裡插入圖片描述 只要呼叫了本類中的方法,這個this就表示當前執行的物件。

2. static關鍵字

在Java類中定義了一個static關鍵字,它用於修飾類的成員,如成員變數、成員方法以及程式碼塊等。

2.1 static屬性(類屬性)

  在定義一個類時,只是在描述某類事物的特徵和行為並沒有產生具體的資料。只有通過new關鍵字建立該類的例項物件後,系統才會為每個物件分配記憶體空間,儲存各自的資料。   但是有時候需要某些特定的資料在記憶體中只有一份,而且能夠被一個類的所有例項物件所共享。 舉例:例項屬性的記憶體分析

class Person{
    String country = "中國";
    String name;
    int age;

    public void getPersonInfo(){
        System.out.println("姓名:" + this.name + ",年齡:" + this.age + ",國家:" + this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        per1.name = "zhangsan";
        per1.age = 10;
        Person per2 = new Person();
        per2.name = "lisi";
        per2.age = 20;

        per1.getPersonInfo();
        per2.getPersonInfo();

    }
}

執行結果如下: 在這裡插入圖片描述 記憶體分析圖如下: 在這裡插入圖片描述 傳統屬性所具備的特徵:儲存在堆記憶體中,且每個物件獨享屬性。 描述共享屬性,只需在屬性前新增static關鍵字即可。 static屬性又稱為類屬性,儲存在全域性資料區的記憶體之中,所有物件都可以進行該資料區的訪問。 修改上述程式碼:

static String country = "中國";

此時的記憶體分析圖如下所示: 在這裡插入圖片描述 結論:

  1. 訪問static屬性應使用 類名稱 . 屬性名
  2. 所有的非static屬性(例項變數)必須在物件例項化後使用,而static屬性不收物件例項化控制
  3. 修改static屬性,所有物件都同步此屬性。應使用一下方法修改:
Person.country = "中國";

定義類時,如何選擇例項變數和類屬性呢?

  1. 在定義類時,99%的情況都不會考慮static屬性,以非static屬性(即例項變數)為主
  2. 如果需要描述共享屬性的概念,或者不受物件例項化控制,使用static

注意:   static關鍵字只能用於修飾成員變數,不能用於修飾區域性變數,否則編譯會報錯,下面程式碼時非法的:

2.2 static方法(類方法)

使用static定義的方法,直接通過類名進行訪問。   類名稱 . 方法名 舉例:觀察static方法

class Person{
    private static String country;
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    public static void setCountry(String s){
        country = s;
    }

    public void getPersonInfo(){
        System.out.println("姓名:"+this.name+",年齡:"+this.age+"國家:"+this.country);
    }
}
public class Test{
    public static void main(String[] args){
        Person per = new Person("zhangsan", 20);
        per.getPersonInfo();
        Person.setCountry("中國");
        per.getPersonInfo();
    }
}

在這裡插入圖片描述 關於static方法有以下兩點說明:

  1. 所有的static方法不允許呼叫非static定義的屬性或方法
  2. 所有的非static方法允許訪問static方法或屬性

使用static定義的方法只有一個目的:某些方法不希望受到類的控制,即可以在沒有例項化物件的時候執行(廣泛存在於工具類中)。 注意:   在一個靜態方法中只能訪問用static修飾的成員,原因在於沒有被static修飾的成員需要先建立物件才能訪問,而靜態方法被呼叫時可以不建立任何物件。   例項物件同樣可以呼叫靜態方法。

public class Test{
    public static void main(String[] args){
        //類名.方法的方式呼叫靜態方法
        Person.setCountry("中國");
        Person per = new Person("zhangsan", 20);
        per.getPersonInfo();
        //例項化物件的方式來呼叫靜態方法
        per.setCountry("China");
        per.getPersonInfo();
    }
}

執行結果如下所示: 在這裡插入圖片描述

由static修飾的還有程式碼塊,稱為 靜態程式碼塊, 這些我們在後面的總結會寫到。