1.static的最主要作用是:
方便在沒有創建對象的情況下進行調用(方法/變量),可以直接通過類名來訪問。
2.在靜態方法裏不可以調用非靜態方法,但是在非靜態方法裏可以調用靜態方法。
3.我們最常見的static方法就是main方法,是因爲想在不創建對象的情況下調用該方法,所以main方法必須是static類型的。
4.即使沒有顯示的聲明爲static方法,類的構造器實際上也是靜態方法。
5.static變量:
靜態變量被所有的對象所共享,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化。而非靜態變量是對象所擁有的,在創建對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。
6.static代碼塊:
static關鍵字還有一個比較關鍵的作用就是 用來形成靜態代碼塊以優化程序性能。static塊可以置於類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,並且只會執行一次。
例如:
class Person{
private Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
Date startDate = Date.valueOf("1946");
Date endDate = Date.valueOf("1964");
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
isBornBoomer是用來這個人是否是1946-1964年出生的,而每次isBornBoomer被調用的時候,都會生成startDate和birthDate兩個對象,造成了空間浪費,如果改成這樣效率會更好:
class Person{
private Date birthDate;
private static Date startDate,endDate;
static{
startDate = Date.valueOf("1946");
endDate = Date.valueOf("1964");
}
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
7.java 中static關鍵字不會影響訪問權限,與之有關的只有private,public,protected關鍵字。
8.可以通過this來訪問靜態成員變量。
9.靜態方法中不可以使用this來訪問類的成員變量或者方法,但是在非靜態方法中可以。
10.在java中,static不允許來修飾局部變量。
一個問題:下面這段代碼的輸出是什麼?
public class Test extends Base{
static{
System.out.println("test static");
}
public Test(){
System.out.println("test constructor");
}
public static void main(String[] args) {
new Test();
}
}
class Base{
static{
System.out.println("base static");
}
public Base(){
System.out.println("base constructor");
}
}
答案是:
base static
test static
base constructor
test constructor
原因:編譯器開始執行的時候,要先去找main方法,找main方法之前會先加載Test類,而在加載Test類的時候發現它繼承自Base類,於是開始要先加載Base類,加載Base類的時候,發現有static塊,便先執行static塊,然後回去加載Test類,發現有static塊,也是先執行塊。加載完所有的類以後,開始執行main方法。在main方法中執行new
Test()的時候會先調用父類的構造器,然後再調用自身的構造器。(只有在new 類的時候會調用構造器,調用構造方法)
下面說一下構造器:
在java中,每一個類都至少有一個構造器。可以這麼理解,構造器就是java中特殊的方法,所以構造器也常被稱爲構造方法。我們根據類來創建對象,就是使用類中的構造器來創建。