參考:Java從入門到精通 第五版 清華大學出版社
有時,在處理數據的時候需要兩個類在同一內存區域中共享一個數據。比如說,在計算圓的面積這一類中需要使用PI這個常量,同樣,在計算球的體積這一類中同樣也要用到。沒有必要去在兩個類分別創建這一個常量PI,因爲這樣會使得系統把這兩個在不同類中定義的同一常量分配到不同的內存空間。
爲此,可將這個常量設置爲靜態的,這個常量在內存中是被共享的。 被聲明爲static的變量,常量和方法被稱爲靜態成員,屬於類所有,區別於個別對象,可在本類或者其他類中使用類名和“.”運算符調用靜態成員。
其定義格式爲:static 數據類型 變量名
看下面一段例子:
public class StaticTset{
final static double pi = 3.14;//定義靜態常量
static int id; //定義靜態變量
public static void method1() { //定義靜態方法
//...
}
public void method2() {
System.out.println(StaticTset.pi); //調用
System.out.println(StaticTset.id); //調用
StaticTset.method1(); //調用
}
}
這裏分別用類名.靜態成員 調用
再看接着的下面一段,這裏編譯的話會報錯,因爲method3是一個靜態方法,而在其中調用了非靜態方法method2和關鍵字this,故報錯。
public static method3(){
method2();
return this;
}
在java中對於靜態方法有兩點規定:
- 靜態方法中不可以使用this關鍵字
- 在靜態方法中不可以直接調用非靜態方法
此外,方法中的局部變量也不能聲明爲static。
通過一段例子來理解這個static:
public class TransferProperty {
int i = 47; // 定義成員變量
public void call() { // 定義成員方法
System.out.println("調用call()方法");
for (i = 0; i < 3; i++) {
System.out.print(i + " ");
if (i == 2) {
System.out.println("\n");
}
}
}
public TransferProperty() { // 定義構造方法
}
public static void main(String[] args) {
TransferProperty t1 = new TransferProperty(); // 創建一個對象
TransferProperty t2 = new TransferProperty(); // 創建另一個對象
t2.i = 60; // 將類成員變量賦值爲60
// 使用第一個對象調用類成員變量
System.out.println("第一個實例對象調用變量i的結果:" + t1.i++);
t1.call(); // 使用第一個對象調用類成員方法
// 使用第二個對象調用類成員變量
System.out.println("第二個實例對象調用變量i的結果:" + t2.i);
t2.call(); // 使用第二個對象調用類成員方法
}
}
//輸出結果:
第一個實例對象調用變量i的結果:47
調用call()方法
0 1 2
第二個實例對象調用變量i的結果:60
調用call()方法
0 1 2
可以看到,對象t1和t2以及局部方法中的i是各自獨立的,改變了t2的i值並不影響t1的i值,成員變量可以被其中任何一個對象改變,這是因爲內存中兩個對象指向不同的區域,。爲了不發生這種情況,使用static關鍵字,即對象調用這個靜態成員變量,其他不變,修改成員變量爲:
static int i = 47
其輸出結果就變爲了:
第一個實例對象調用變量i的結果:60
調用call()方法
0 1 2
第二個實例對象調用變量i的結果:3
調用call()方法
0 1 2
可以看到,語句t2.i = 6修改了靜態成員變量的值,這時兩個對象指向的是同一塊內存區域,故t1.i也發生了變化,同理局部變量i