java 常用關鍵字—— final 和 static

final

1. 數據

聲明數據爲常量,可以是編譯時常量,也可以是在運行時被初始化後不能被改變的常量。

  • 對於基本類型,final 使數值不變;
  • 對於引用類型,final 使引用不變,也就不能引用其它對象,但是被引用的對象本身是可以修改的。
final int x = 1;
// x = 2;  // cannot assign value to final variable 'x'
final int a;
a = 5;
// a = 7; // cannot assign value to final variable 'a'
final A y = new A();
y.a = 1;

2. 方法

聲明方法不能被子類重寫。

private 方法的作用域在該類中,如果在子類中定義的方法和基類中的一個 private 方法簽名相同,此時子類的方法不是重寫基類方法,而是在子類中定義了一個新的方法。

3. 類

聲明類不允許被繼承。

static

1. 靜態變量

  • 靜態變量:又稱爲類變量,也就是說這個變量屬於類的,類所有的實例都共享靜態變量,可以直接通過類名來訪問它;靜態變量在內存中只存在一份。
  • 實例變量:每創建一個實例就會產生一個實例變量,它與該實例同生共死。
public class A {
    private int x;         // 實例變量
    private static int y;  // 靜態變量

    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;
    }
}

2. 靜態方法

靜態方法在類加載的時候就存在了,它不依賴於任何實例。所以靜態方法必須有實現,也就是說它不能是抽象方法(abstract)。

public abstract class A {
    public static void func1(){
    }
    // public abstract static void func2();  // Illegal combination of modifiers: 'abstract' and 'static'
}

只能訪問所屬類的靜態字段和靜態方法,方法中不能有 this 和 super 關鍵字。

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
    }
}

3. 靜態語句塊

靜態語句塊在類初始化時運行一次。

public class A {
    static {
        System.out.println("123");
    }

    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
    }
}
123

4. 靜態內部類

非靜態內部類依賴於外部類的實例,而靜態內部類不需要。

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();
    }
}

靜態內部類不能訪問外部類的非靜態的變量和方法。

5. 靜態導包

在使用靜態變量和方法時不用再指明 ClassName,從而簡化代碼,但可讀性大大降低。

import static com.xxx.ClassName.*

6. 初始化順序

靜態變量和靜態語句塊優先於實例變量和普通語句塊,靜態變量和靜態語句塊的初始化順序取決於它們在代碼中的順序。

public static String staticField = "靜態變量";
static {
    System.out.println("靜態語句塊");
}
public String field = "實例變量";
{
    System.out.println("普通語句塊");
}

最後纔是構造函數的初始化。

public InitialOrderTest() {
    System.out.println("構造函數");
}

存在繼承的情況下,初始化順序爲:

  • 父類(靜態變量、靜態語句塊)
  • 子類(靜態變量、靜態語句塊)
  • 父類(實例變量、普通語句塊)
  • 父類(構造函數)
  • 子類(實例變量、普通語句塊)
  • 子類(構造函數)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章