JAVA static 詳解
在java中,static是完全避不開的一個問題,這也是衆多面試官老生常談的一個問題,所以對static的瞭解需要更進一步;
首先,你可以瞭解一下c++中static的作用和使用:c++中static的總結
static的用法
在《java核心技術卷一》中p112用了一章的一個小節講解了“靜態域和靜態方法。
在《Java編程思想》P86頁有這樣一段話:
static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是可以的。而且可以在沒有創建任何對象的前提下,僅僅通過類本身來調用static方法。這實際上正是static方法的主要用途。
1. 方便在沒有創建對象的情況下來進行調用(方法/變量)。
很顯然,被static關鍵字修飾的方法或者變量不需要依賴於對象來進行訪問,只要類被加載了,就可以通過類名去進行訪問。
static可以用來修飾類的成員方法、類的成員變量,另外可以編寫static代碼塊來優化程序性能。
靜態域
如果將域定義爲static,每個類中只有一個這樣的域。而每一個對象對於所有的實例域卻都有自己的一份拷貝
1.這句話就說明聲明瞭n個對象,
則非static的域有n個,而static的域只有一個
所有對象共享這一個static域
class Employee
{
//static的域
private static int nextId =1;
//非static的域
private int id;
}
靜態常量
靜態變量一般使用得少,而靜態常量卻使用得較多。
定義爲靜態常量的量可以不用創建對象來訪問,可以通過類名直接調用
- Math中的PI常量
如Math類中的PI常量
public class Math
{
...
public static final double PI = 3.1415926538979323846;
...
}
在程序中調用這個常量就可以直接使用Math.PI來獲得這個常量。
- 如果用static的常量,則創建多少個對象,就有多少個常量的拷貝,可以直接用類名.靜態常量來獲取這個常量
- 如果省略static,則每個對象都有自己的一份常量的拷貝,必須通過類創建的對象來獲取這個常量
- System類中的out
public class System
{
...
public static final PrintStream out=...;
...
}
靜態方法
使用靜態方法的時候不需要創建任何對象,靜態方法的語法格式是:類名.方法名();
如 Math.pow(x,a)
《java核心技術卷一》p114
在下面兩種情況下使用靜態方法:
- 一個方法不需要訪問對象狀態,其所需參數都是通過顯示參數提供(例如:Math.pow)
- 一個方法只需要訪問類的靜態域(例如:Employee.getNextId)
這裏需要注意到的是 參數分爲兩類
- 隱式參數:出現在方法名前的類名或者類對象
- 顯式參數:位於方法名後面括號中的數值,可以理解爲參數表
還有一點值得注意,就是java中的static含義和c++中的含義相同,即屬於類且不屬於類對象的變量和函數
工廠方法
這裏有一個知識點要注意:
構造對象有兩種方法:
- 構造器方法:如 Student stu =new Student(2018,“計算機”,2018xxx);
- 工廠方法:LocalDate today = LocalDate.now();
下面的情況:
NumberFormat currencyFormatter = NumberFormat,getCurrencyInstance();
NumberFormat percentFormatter = NumberFormat.getPercentInstance();
double x = 0.1;
System.out.println(currencyFormatter(x));//print $0.10
System.out.println(percentFormatter(x));//print 10%
這裏使用工廠方法構造對象的原因:
- 無法命名構造器。構造器的名字必須與類名相同。但是有時候,希望將得到的貨幣實例和百分比實例採用不同的名字。
- 當使用構造器時,無法改變所構造的對象類型。而工廠方法將返回一個DecimalFormat的類對象,這是NumberFormat的子類。
main方法
這裏有一個小技巧
可以在每一個類創建一個main方法,這是一個常用於對類進行單元測試的技巧
這時候如果要獨立測試這個類,只需要執行
java 類名
如果是一個更大型應用程序的一部分,可以用下面的語句運行程序
java Application
這時候要測試類的main方法永遠不會執行
static代碼塊
static關鍵字還有一個比較關鍵的作用就是 用來形成靜態代碼塊以優化程序性能。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。
爲什麼說static塊可以用來優化程序性能,是因爲它的特性:只會在類加載的時候執行一次。
具體內容可以參看下面這位大牛的博客:傳送門