Java的static和final關鍵字的用法


static關鍵字的用法

  static的意思是“’靜態的”,在java里面可用於修飾屬性和方法。

  static關鍵字的應用應注意以下幾種情形:  

    1.static作用於某個字段,一個static字段對每個類來說只有一份存儲空間,而非static字段是每個對象有一份存儲空間。

    2.static作用於方法的重要用法是不需要創建任何對象直接調用該static方法,這對於main()方法很重要。

    3.static不能應用於局部變量。

    4.Java中禁止使用全局方法,所以引入static方法通過類本身來直接調用。

package cn.wangze.test;

class Demo{
    public static int i = 19;
}

public class staticDemo {
    private static Demo demo1 = new Demo();
    private static Demo demo2 = new Demo();
    public static void main(String[] args){
        System.out.println(Demo.i);     //19
        System.out.println(demo1.i);    //19
        System.out.println(demo2.i);    //19
        demo1.i++;
        System.out.println(Demo.i);        //20
        System.out.println(demo1.i);    //20
        System.out.println(demo2.i);    //20
        Demo.i++;
        System.out.println(Demo.i);        //21
        System.out.println(demo1.i);    //21
        System.out.println(demo2.i);    //21
    }
}

  上面程序的輸出結果驗證了上面兩條,帶有static關鍵字的數據在內存中占有一塊固定內存地址,你可以用類名直接調用,也可以創建對象來調用,推薦ClassName.method()來調用。當我們改變它的值,任何地方的調用也會隨之改變。

  Java系統自帶的Math、UUID、Class等常用的工具類就是用的這種方式。

 為什么要將方法和變量都寫成靜態的。
 因為,這些方法我只是想調用一下,不需要牽扯工具類中的任何屬性和變量,所以,我就沒有必要實例化了(new)。既然不需要實例化了,那么就用靜態就行了。

  你也可以在實際項目中根據業務需求來聲明自己的工具類,只需要加入static關鍵字,引入該類后使用類名.方法名()調用即可。

  需要注意的一點是,類的加載和初始化過程中,帶有static的數據會最先加載並調用,其次是構造器的加載,最后才是普通成員變量和方法的加載。

 

final關鍵字的用法

  final意味着"不可改變的",一般應用於數據、方法和類。

final數據

    當數據是基本類型時,意味着這是一個永不改變的編譯時常量,一個在運行時被初始化的值,你不希望它改變。

    當數據是引用類型時,用static和final修飾表示這是只占據一塊不能改變的內存空間。

    有一條約定成俗的規定是使用stati和final修飾的變量即編譯期常量應該用全部大寫字母表示,例如:

package cn.wangze.test;

import java.util.*;

class Value{
    int i;
    public Value(int i){
        this.i = i;
    }
}

public class FinalData {
    private static Random rand = new Random(47);
    private String id;
    public FinalData(String id){
        this.id = id;
    }
    private final int value_one = 9;
    private static final int VALUE_TWO = 99;
    public static final int VALUE_THREE = 39;
    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);
    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    static final Value V3 = new Value(33);
    private final int[] a = {1,2,3,4,5,6};
    @Override
    public String toString(){
        return id+", i4="+i4+",INT_5 = "+INT_5;
    }
    public static void main(String[] args){
        FinalData fd1 = new FinalData("fd1");
        //fd1.value_one++; 錯誤,final修飾的基本類型數據的值不能改變
        fd1.v2.i++;
        fd1.v1 = new Value(9); //可以操作,因為v1不是final數據
        //fd1.v2 = new Value(0);  錯誤,final修飾的引用類型數據的內存地址不能改變
        //fd1.v3 = new Value(5);  錯誤,final修飾的引用類型數據的內存地址不能改變
        //fd1.a = new int[3];  /錯誤,final修飾的引用類型數據的內存地址不能改變
        System.out.println(fd1);   // fd1, i4=15,INT_5 = 18
        System.out.println("creating new FinalData");
        FinalData fd2 = new FinalData("fd2");  
        System.out.println(fd1);     //fd1, i4=15,INT_5 = 18
        System.out.println(fd2);    //fd2, i4=13,INT_5 = 18
    }
}

    上面例子驗證了final修飾的基本數據類型和引用數據類型的區別。根據i4和INT_5的輸出值可以得出結論,在編譯期我們不能因為數據是final 的就可以知道它的值,只有在運行時才會確定它的值。同時這里也展示了靜態和非靜態的區別,帶有static關鍵字的數據在裝載時被初始化,非靜態的數據是在創建對象時間初識化的。例如:

package cn.wangze.test;

class useDemo{
    private int i;
    public useDemo(int ii){
        i = ii;
    }
}

public class BlankFinal {
    private final int i = 9;
    private final int j;
    private final useDemo ud;
    public BlankFinal(){
        j = 1;
        ud = new useDemo(10);
    }
    public BlankFinal(int x){
        j = 2;
        ud = new useDemo(x);
    }
    public static void main(String[] args){
        new BlankFinal();
        new BlankFinal(55);
    }
}

   上面例子我們在定義final變量是沒有給其賦值,這並沒有錯,但是一定要在構造器中給其賦值,不然編譯都不會通過。

  2、fianl參數

    當我們把方法傳入的形參定義為fianl時候,代表我們並不想在方法內部改變此參數的引用。

    public void change( final useDemo u2){
        u2.i = 20;
        //u2 = new useDemo(20); 報錯
    } 

    事實是當我們不帶有final關鍵字時,函數內部的引用改變也不會對外界的實參產生影響,所以我認為這里final的作用是編譯期的阻攔,起到一個警示的作用。

  3、fianl方法

    一般我們使用final方法的目的就是防止子類對該類方法的覆蓋或修改。

    類中的所有private方法都隱式的制定為final的。因為private方法只會在本類顯示,即使是子類也不能操作該方法。有時候我們在子類中聲明與父類private方法相同名稱的方法,這樣並不會報錯,實際上我們並沒有覆蓋或者修改父類的private 方法,它只是一個和父類private方法具有相同名稱的新方法。

  4、fianl類

    一般我們使用final類的目的就是說明我們不打算用任何類繼承該類,即不希望該類有子類。

    帶有final關鍵字的類,其內部所有方法和數據都是隱式帶有final關鍵字的,因為沒有類可以繼承該類,代表着任何外界因素可以改變它的數據。

  總結:

    在我們設計程序的時候,會根據業務需求來決定是否對數據或方法或類帶有static和final關鍵字,這很重要,從另一個角度來說,final和static關鍵字的合理應用確實可以提高程序的效率,減少內存的消耗,當我們了解了類的初始化和加載過程,可能會對final和static有一個更加直觀的認識。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM