1. 程式人生 > 其它 >Java-final、static關鍵字

Java-final、static關鍵字

知識點1- final的定義

  • 在Java中,final關鍵字有最終的,不可修改的含義

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

    屬性:定義就必須直接賦值或者在構造方法中進行賦值,並且後期都不能修改。

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

    類:不能被定義為抽象類或是介面,不可被繼承。

知識點2- final修飾屬性

  • 如果某個變數被final修飾,那麼該變數就成為常量,不能被修改,一般語法:

  

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

  • 規範:定義常量的時候,變數名所有字母都大寫,每個單詞之間使用下劃線

  • 賦值兩種方式:構造方法賦值和宣告時等號賦值

  • 一些數學定理中的常量經常使用final修飾

    eg:π= 3.14159265358979; E= 2.718281828459045;

  • 對引數做final修飾

    • 在方法引數前面加final關鍵字,為了防止資料在方法體中被修改。

package com.tjetc.myfinal;
public class FinalTest {
    //方式一:定義常量直接賦值
    public static final int USER_ROLE = 1; //final修改屬性,屬性就是常量,不能二次賦值
    //public static final int ADMIN_ROLE; 
//當使用方法二構造方法進行給常量值賦值的情況,不能使用static public final int ADMIN_ROLE; // new一個物件開記憶體空間,常量的值是不變的,意味著沒有必要為常量開多個記憶體空間。多個物件共享一個常量,static保證多個物件共享一個。 // 一般情況:定義常量static+final一起用 //方式二:構造方法給常量賦值 public FinalTest(int adminRole) { this.ADMIN_ROLE = adminRole; } public void test() {
//USER_ROLE=2; //不能二次賦值 System.out.println("常量USER_ROLE=" + USER_ROLE); System.out.println("常量ADMIN_ROLE=" + ADMIN_ROLE); } public static void main(String[] args) { FinalTest test = new FinalTest(6); test.test(); System.out.println("常量USER_ROLE=" + test.USER_ROLE); } } /** * 常量USER_ROLE=1 * 常量ADMIN_ROLE=6 * 常量USER_ROLE=1 */

知識點3- final修飾方法

  • 如果將某個成員方法修飾為final,則意味著該方法不能被子類覆蓋,這就和抽象方法必須由子類實現的規定互相矛盾,因此,final和abstract不能同時修飾一個方法

  • final方法的一般宣告格式是:

知識點4- final修飾類

  • 如果將某個類修飾為final,則說明該類無法被繼承,一般語法:

  • Java中有一個最常用的final類:java.lang.String

知識點5-靜態的定義

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

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

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

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

知識點6-靜態成員變數

  • 被static修飾的成員變數被稱為靜態成員變數或者是靜態屬性

    package com.tjetc.myfinal;
    public class Employee {
        String name;
        double salary;
        //預設是0  靜態成員變數  是所有物件共享的一個成員變數,可以使用物件呼叫也可以使用類名稱呼叫
        static int count;
        //預設是0  成員變數    每個物件 有各自的成員變數,不共享的
        int myCount;
        public Employee(String name, double salary) {
            this.name = name;
            this.salary = salary;
            //讓count和myCount 都自增1
            count++;
            myCount++;
        }
        public static void main(String[] args) {
            Employee e1 = new Employee("carat", 10000);
            System.out.println("姓名:" + e1.name + "\t工資:" + e1.salary + "\tcount:" + e1.count + "\tmyCount:" + e1.myCount);
            Employee e2 = new Employee("seventeen", 15000);
            System.out.println("姓名:" + e2.name + "\t工資:" + e2.salary + "\tcount:" + e2.count + "\tmyCount:" + e2.myCount);
        }
    }
    /**
     * 姓名:carat    工資:10000.0    count:1    myCount:1
     * 姓名:seventeen    工資:15000.0    count:2    myCount:1
     */

知識點7-靜態方法

  • 如果某個方法不需要與某個特定的物件繫結,那麼該方法可以使用static修飾,被static修飾的方法稱為靜態方法。

  • 靜態方法如何呼叫:static方法可以使用物件呼叫,也可以直接用類名呼叫,建議用類名直接呼叫。

    
    
    
    package com.tjetc.myfinal;
    public class SellTicket {
        private static int a = 10;//靜態成員變數
        private int b;   //成員變數
    
        //靜態方法 能夠只用靜態的成員變數
        public static void sell() {
            //靜態方法中 可以定義區域性變數並且使用
            int c = 4;
            System.out.println("使用區域性變數c=" + c);
            //靜態方法 不能夠使用成員變數(非靜態)
            //b = 2;b無法使用
            a -= 1;
            System.out.println("使用靜態成員變數:" + a);
        }
        public static void main(String[] args) {
            //通過類名呼叫方法,以下兩種都可以
            SellTicket.sell();
            sell();
            //通過物件名呼叫
            SellTicket sell1 = new SellTicket();
            sell1.sell();
        }
    }
    /**
     * 使用區域性變數c=4
     * 使用靜態成員變數:9
     * 使用區域性變數c=4
     * 使用靜態成員變數:8
     * 使用區域性變數c=4
     * 使用靜態成員變數:7
     */

知識點7-靜態方法-總結

  • 本類的方法之間的呼叫

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

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

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

  • 不同類方法之間的呼叫

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

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

知識點8-靜態程式碼塊

  • static程式碼塊

    隨著類的載入而載入,只執行一次,用於給類進行初始化

    看JVM載入類的過程:裝載、連線、初始化(靜態程式碼塊,靜態變數)

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

  • 構造程式碼塊(例項程式碼塊)

  • 構造方法給物件初始化

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

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

package mystatic;
//優先父類初始化
class HelloA {
    public HelloA() {
        System.out.println("HelloA");
    }
    //在例項化物件過沖程中,早於構造方法執行
    {
        System.out.println("I'm A class");
    }
    //static塊的執行發生在“初始化”的階段。初始化階段,jvm主要完成對靜態變數的初始化,靜態塊執行等工作。在例項化物件之前
    static {
        System.out.println("static A");
    }
}
class HelloB extends HelloA {
    public HelloB() {
        System.out.println("HelloB");
    }

    {
        System.out.println("I'm B class");
    }

    static {
        System.out.println("static B");
    }

    public static void main(String[] args) {
        new HelloB();
    }
}
/**
 * static A
 * static B
 * I'm A class
 * HelloA
 * I'm B class
 * HelloB
 */

知識點9-Static Import機制

  • JDK1.5中引入了“Static Import”機制,藉助這一機制,可以用略掉所在的類或介面名的方式,來使用靜態成員

  • 之前我們是這樣呼叫靜態方法的:

  • 現在可以這樣簡化