1. 程式人生 > 其它 >final與static

final與static

                                        final static 整理

final:

  • final 用於宣告屬性,方法和類

  • 屬性:定義就必須直接賦值或者在構造方法中進行賦值,並且後期都不能修改(使用場景:某一個變數,值是不改變,無論哪個物件呼叫值都是一樣的,就可以用final修飾為常量)

    • 常量在宣告時必須初始化宣告之後不能對其進行二次賦值,其後任何試圖對常量進行賦值的語句都將報錯。

    • 語法形式:語法:[訪問許可權修飾符 final 資料型別 常量名 = 值;
    • 常量命名:全部大寫,多個單詞之間是有_分割
    • 一些數學定理中的常量經常使用final修飾(eg:π= 3.14159265358979; E= 2.718281828459045)
    • 賦值兩種方式:構造方法賦值和宣告時等號賦值
    • final int c=1;   static final b=1;
    • 這裡c和b的區別在於,b存放在靜態空間,不會在程式執行時被釋放,它永遠佔著記憶體直到程式終止,而c在程式用完它而不會再用到它的時候就會被自動釋放,不再佔用記憶體。當一個常數或字串我們需要在程式裡反覆反覆使用的時候,我們就可以把它定義為static final,這樣記憶體就不用重複的申請和釋放空間。

    方法:定義必須有實現程式碼,並且子類裡不可被覆蓋。

  •  注意: final和abstract不能同時修飾一個方法
  • 類:不能被定義為抽象類或是介面,不可被繼承。

Static:

  • static被稱為靜態,可以用來修飾類的屬性或者方法。

  • 如果類的某個屬性,不管建立多少個物件,屬性的儲存空間只有唯一的一個,那麼這個屬性就應該用static修飾,被static修飾的屬性被稱為靜態屬性,被static修飾的方法被稱為靜態方法。

  • static屬性可以使用物件呼叫,也可以直接用類名呼叫。

  • 靜態屬性是類的所有物件共享的,即不管建立了多少個物件,靜態屬性在記憶體中只有一個。

  • eg:
    public class Employee {
        String name;  //員姓名
        double salary; //員工工資
        static int count; // 靜態變數 員工數量
        int myCount = 0; //成員變數

        //無參構造
        public Employee() {
        }

        //有參構造
        public Employee(String name, double salary) {
            this.name = name;
            this.salary = salary;
            count++;  //員工數量自加1
            myCount++; //自增1
        }

        //測試方法
        public static void main(String[] args) {
            Employee e1 = new Employee("lily", 9000);    //建立lily的物件
            System.out.println("name:" + e1.name + "\tsalary:" + e1.salary + "\tmyCount:" + e1.myCount + "\tcount:" + Employee.count); // lily 9000 1 1
            Employee e2 = new Employee("alice", 3000);   //建立alice的物件
            System.out.println("name:" + e2.name + "\tsalary:" + e2.salary + "\tmyCount:" + e2.myCount + "\tcount:" + e2.count); //alice  3000  1  2
        }
    }
  • 可見,輸出的count都為2,說明兩個物件呼叫的count是一個記憶體空間的值,而mycount分別是1。可以理解例項變數和靜態變數的區別。靜態的屬性與物件沒有關係,是所有物件共享的,只與類有關。

靜態方法總結

  • 本類的方法之間的呼叫

    • 靜態方法可以被任何方法(靜態方法和非靜態方法)直接呼叫;

    • 非靜態方法可以被非靜態方法直接呼叫;

    • 非靜態方法不能被靜態方法直接呼叫,需要建立物件,用物件名呼叫。

  • 不用類方法之間的呼叫

    • 呼叫靜態方法,使用類名直接呼叫 ;

    • 非靜態方法不能直接呼叫,需要建立物件,用物件名呼叫。

    • 例題:

      public class StaticTest {
          //測試本來之間靜態方法和非靜態方法之間的呼叫
          //靜態方法
          public static void f() {
              StaticTest test = new StaticTest();
              test.a();  //靜態----非靜態    建立物件,通過物件名呼叫

              StaticTest.g();  // 靜態---靜態   直接通過類名呼叫

          }
          //靜態方法
          public static void g() {

          }
          //非靜態方法
          public void a() {
              StaticTest.g();   //非靜態---靜態   直接類名呼叫
              b();    //非靜態--非靜態    直接呼叫
          }
          //非靜態方法
          public void b() {
          }
          //不同類之間的呼叫   呼叫靜態方法---使用類名  呼叫非靜態方法---建立物件,通過物件名呼叫
      }
    • 靜態程式碼塊:
      • 非雖著類的載入而載入,只執行一次,用於給類進行初始化

        看JVM類載入的過程:裝載、連線、初始化

        static塊的執行發生在“初始化”的階段。初始化階段,jvm主要完成對靜態變數的初始化,靜態塊執行等工作。

      • 構造程式碼塊

        構造方法給物件初始化

      • static程式碼塊和構造程式碼塊同時出現時優先順序

        靜態程式碼塊>構造程式碼塊>構造方法