靜態域 **如果將域定義為 static,每個類中只有一個這樣的域。而每一個對象對於所有的實例域卻都有自己的一份拷貝。**例如,假定需要給每一個雇員賦予唯一的標識碼。這裡給 Employee 類添加一個實例域 id 和一個靜態域 nextld: class Employee { private st ...
靜態域
如果將域定義為 static,每個類中只有一個這樣的域。而每一個對象對於所有的實例域卻都有自己的一份拷貝。例如,假定需要給每一個雇員賦予唯一的標識碼。這裡給 Employee 類添加一個實例域 id 和一個靜態域 nextld:
class Employee {
private static int nextId = 1;
private int id;
}
現在,每一個雇員對象都有一個自己的 id 域,但這個類的所有實例將共用一個 nextId 域。換句話說,如果有 1000 個 Employee 類的對象,則有 1000 個實例域 id。但是,只有一個靜態域 nextld。即使沒有一個雇員對象,靜態域 nextld 也存在。靜態域它屬於類,而不屬於任何獨立的對象。
靜態常量
靜態變數使用得比較少,但靜態常量卻使用得比較多。例如,在 Math 類中定義了一個靜態常量:
public class Math {
public static final double PI = 3.14159265358979323846;
}
在程式中,可以採用 Math.PI 的形式獲得這個常量。
如果關鍵字 static 被省略,PI 就變成了 Math 類的一個實例域。需要通過 Math 類的對象訪問 PI,並且每一個 Math 對象都有一份它自己的 PI 拷貝。
另一個多次使用的靜態常量是 System.out。它在 System 類中聲明:
public class System {
public static final PrintStream out = ...;
}
由於每個類對象都可以對公有域進行修改,所以,最好不要將域設計為 public。然而,公有常量(即 public static final 域)卻沒問題。 因為 out 被聲明為 final,所以不允許再將其他列印流賦值給 out。
靜態方法
靜態方法是一種不能向對象實施操作的方法。例如,Math 類的 pow() 方法就是一個靜態方法。表達式 Math.pow(x, a) 計算冪 xa。在計算時不使用任何 Math 對象。換句話說,沒有隱式的參數。
可以認為靜態方法是沒有 this 參數的方法(在一個非靜態的方法中,this 參數表示這個方法的隱式參數。)
Employee 類的靜態方法不能訪問 id 實例域,因為它不能操作對象。但是,靜態方法可以訪問自身類中的靜態域。下麵是使用這種靜態方法的一一個示例:
public static int getNextId() {
return nextId; // returns static field
}
可以通過類名調用這個方法:int n = Employee.getNextId();
在下麵兩種情況下使用靜態方法:
- 一個方法不需要訪問對象狀態,其所需參數都是通過顯式參數提供(例如:Math.pow())
- 一個方法只需要訪問類的靜態域(例如:Employee.getNextId())
Java 中的靜態域與靜態方法在功能上與 C++ 相同。但是,語法書寫上卻稍有所不同。在 C++ 中,使用 :: 操作符訪問自身作用域之外的靜態域和靜態方法,如 Math::PI。
工廠方法
靜態方法還有另外一種常見的用途。類似 LocalDate 和 NumberFormat 的類使用靜態工廠方法(factory method)來構造對象。你已經見過工廠方法 LocalDate.now() 和 LocalDate.of()。
NumberFormat 類如下使用工廠方法生成不同風格的格式化對象:
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
NumberFormat percentFormatter = NumberFormat.getPercentlnstance();
double x = 0.1;
System.out.println(currencyFormatter.format(x)); // prints $0.10
System.out.println(percentFomatter.format(x)); // prints 10%
為什麼 NumberFormat 類不利用構造器完成這些操作呢?這主要有兩個原因:
- 無法命名構造器。構造器的名字必須與類名相同。但是,這裡希望將得到的貨幣實例和百分比實例採用不用的名字。
- 當使用構造器時,無法改變所構造的對象類型。而 Factory 方法將返回一個 DecimalFormat 類對象,這是 NumberFormat 的子類。
參考資料
《Java核心技術捲一:基礎知識》(第10版)第 4 章:對象與類 4.4 靜態域與靜態方法
本文來自博客園,作者:真正的飛魚,轉載請註明原文鏈接:https://www.cnblogs.com/feiyu2/p/17354575.html