------------------------------------------------------------------------CyC2018
- 靜態(tài)變量
靜態(tài)變量:又稱為類變量,也就是說這個變量屬于類的,類所有的實例都共享靜態(tài)變量,可以直接通過類名來訪問它。靜態(tài)變量在內(nèi)存中只存在一份。
實例變量:每創(chuàng)建一個實例就會產(chǎn)生一個實例變量,它與該實例同生共死。
public class A {
private int x; // 實例變量
private static int y; // 靜態(tài)變量
public static void main(String[] args) {
// int x = A.x; // Non-static field 'x' cannot be referenced from a static context
A a = new A();
int x = a.x;
int y = A.y;
}
}
- 靜態(tài)方法
靜態(tài)方法在類加載的時候就存在了,它不依賴于任何實例。所以靜態(tài)方法必須有實現(xiàn),也就是說它不能是抽象方法。
public abstract class A {
public static void func1(){
}
// public abstract static void func2(); // Illegal combination of modifiers: 'abstract' and 'static'
}
只能訪問所屬類的靜態(tài)字段和靜態(tài)方法,方法中不能有 this 和 super 關(guān)鍵字,因此這兩個關(guān)鍵字與具體對象關(guān)聯(lián)。
public class A {
private static int x;
private int y;
public static void func1(){
int a = x;
// int b = y; // Non-static field 'y' cannot be referenced from a static context
// int b = this.y; // 'A.this' cannot be referenced from a static context
}
}
- 靜態(tài)語句塊
靜態(tài)語句塊在類初始化時運行一次。
public class A {
static {
System.out.println("123");
}
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
123
- 靜態(tài)內(nèi)部類
非靜態(tài)內(nèi)部類依賴于外部類的實例,也就是說需要先創(chuàng)建外部類實例,才能用這個實例去創(chuàng)建非靜態(tài)內(nèi)部類。而靜態(tài)內(nèi)部類不需要。
public class OuterClass {
class InnerClass {
}
static class StaticInnerClass {
}
public static void main(String[] args) {
// InnerClass innerClass = new InnerClass(); // 'OuterClass.this' cannot be referenced from a static context
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
StaticInnerClass staticInnerClass = new StaticInnerClass();
}
}
靜態(tài)內(nèi)部類不能訪問外部類的非靜態(tài)的變量和方法。
- 靜態(tài)導(dǎo)包
在使用靜態(tài)變量和方法時不用再指明 ClassName,從而簡化代碼,但可讀性大大降低。
import static com.xxx.ClassName.*
- 初始化順序
靜態(tài)變量和靜態(tài)語句塊優(yōu)先于實例變量和普通語句塊,靜態(tài)變量和靜態(tài)語句塊的初始化順序取決于它們在代碼中的順序。
public static String staticField = "靜態(tài)變量";
static {
System.out.println("靜態(tài)語句塊");
}
public String field = "實例變量";
{
System.out.println("普通語句塊");
}
最后才是構(gòu)造函數(shù)的初始化。
public InitialOrderTest() {
System.out.println("構(gòu)造函數(shù)");
}
存在繼承的情況下,初始化順序為:
父類(靜態(tài)變量、靜態(tài)語句塊)
子類(靜態(tài)變量、靜態(tài)語句塊)
父類(實例變量、普通語句塊)
父類(構(gòu)造函數(shù))
子類(實例變量、普通語句塊)
子類(構(gòu)造函數(shù))