“讓我們進入一個新話題。現在,我想討論一下靜態變量和方法。”
“Ellie,我已經了解了靜態變量和方法。但我想了解更多細節。”
“當我們在類中聲明變量時,我們定義這些變量是否只創建一次,或者類的每個實例(對象)是否都有自己的副本。默認情況下,為每個對象創建一個新的變量副本.這是它的樣子:“
class Cat // Class
{
String name; // Variable
Cat(String name) // Constructor
{
this.name = name; // Variable initialization
}
}
Cat cat1 = new Cat("Oscar"); // Create one object whose name variable contains "Oscar"
Cat cat2 = new Cat("Missy"); // Create one object whose name variable contains "Missy"
System.out.println(cat1.name);
System.out.println(cat2.name);
Oscar
Missy
“儘管在同一個類 (Cat) 中聲明,變量cat1.name
和cat2.name
包含不同的值,因為它們引用不同的對象。”
“這就說得通了。”
“但是,類的每個實例只存在一個靜態變量的副本,並且必須使用類名訪問它。”
class Cat // Сlass
{
String name; // Instance (non-static) variable
static int catCount; // Static variable
Cat(String name)
{
this.name = name;
Cat.catCount++; // Increment the static variable by 1
}
}
System.out.println(Cat.catCount);
Cat cat1 = new Cat("Oscar");
System.out.println(Cat.catCount);
Cat cat2 = new Cat("Missy");
System.out.println(cat1.name);
System.out.println(cat2.name);
System.out.println(Cat.catCount);
0
1
Oscar
Missy
2
“行,這也有道理。”
“Java 方法分為兩類。實例方法在對像上調用並可以訪問該對象的數據。 靜態方法沒有這種訪問權限,因為它們根本沒有對象引用。但是,它們可以引用類的靜態變量和其他靜態方法。
靜態方法不能處理非靜態方法或非靜態變量!”
“這是為什麼,艾莉?”
“每個實例變量都包含在一個對像中。只有當您有對該對象的引用時才能訪問它。靜態方法沒有這樣的引用。”
“實例方法有這樣的引用嗎?”
“是的,它間接傳遞給實例方法。調用實例方法的對象的引用間接傳遞給實例方法。存儲此引用的變量稱為this。這允許方法始終訪問對象的數據或在同一個對像上調用另一個非靜態方法。
null 不是對象引用,而是傳遞給靜態方法。這就是為什麼他們不能處理非靜態變量和方法。他們根本沒有對與這些變量和方法關聯的對象的引用。”
“好的,艾莉,我明白了。”
“這就是非靜態方法的工作原理:
代碼是什麼樣的
|
到底發生了什麼
|
當您使用 <object> 點 <method name> 調用一個方法時,您實際上是在調用一個類方法並將同一個對像作為第一個參數傳遞。在方法內部,對象稱為“this”。方法中的所有操作都在此對象及其數據上執行。” |
“下面是靜態方法的工作原理:
代碼是什麼樣的
|
到底發生了什麼
|
當你調用一個靜態方法時,沒有對像被傳遞給它。換句話說,“this”等於null。這就是靜態方法無法訪問非靜態變量和方法的原因(因為它沒有任何內容可以隱式傳遞給非靜態方法)。” |
“如果變量或方法前面有關鍵字 static,則它是靜態的。”
“如果這些方法受到如此嚴重的限制,為什麼還需要這些方法?”
“嗯,這樣的方法確實有好處。”
“首先,我們不必傳遞對象引用即可使用靜態方法和變量。 ”
“其次,有時需要一個變量只有一個副本。例如,System.out(System 類的靜態輸出變量)。”
“第三,有時你需要調用一個方法才能創建對象。”
“艾莉,你能舉個例子嗎?”
“為什麼你認為main()方法是靜態的?它是靜態的,所以程序員可以在將類加載到內存後,在創建任何對象之前立即調用它。”
GO TO FULL VERSION