Java-Final關鍵字

Java-Final關鍵字

Final成員變量

final修飾的成員變量必須由程序員顯式的指定初始值

final修飾的類變量:

  • 靜態(tài)初始塊中指定初始值或者聲明該變量時指定初始值

  • 而且只能在兩個地方的其中之一指定

final修飾的實例變量:

  • 非靜態(tài)初始塊,聲明該實例變量或構造函數(shù)中指定初始值

  • 只能在三個中的一個指定

實例變量不能在靜態(tài)初始塊中指定初始值,因為靜態(tài)初始塊是靜態(tài)成員惜辑,不可訪問實例變量---非靜態(tài)成員

類變量不能在普通初始塊中指定初始值,因為類變量在類初始化階段已經(jīng)被初始化了

public class FinalVariableTest {

    // 定義成員變量時指定默認值几晤,合法。
    final int a = 6;
    // 下面變量將在構造器或初始化塊中分配初始值
    final String str;
    final int c;
    final static double d;
    // 既沒有指定默認值植阴,又沒有在初始化塊蟹瘾、構造器中指定初始值,
    // 下面定義的ch實例變量是不合法的掠手。
    // final char ch;
    // 初始化塊憾朴,可對沒有指定默認值的實例變量指定初始值
    {
        //在初始化塊中為實例變量指定初始值,合法
        str = "Hello";
        // 定義a實例變量時已經(jīng)指定了默認值喷鸽,
        // 不能為a重新賦值伊脓,因此下面賦值語句非法
        // a = 9;
    }
    // 靜態(tài)初始化塊,可對沒有指定默認值的類變量指定初始值
    static
    {
        // 在靜態(tài)初始化塊中為類變量指定初始值魁衙,合法
        d = 5.6;
    }
    // 構造器,可對既沒有指定默認值株搔、有沒有在初始化塊中
    // 指定初始值的實例變量指定初始值
    public FinalVariableTest()
    {
        // 如果在初始化塊中已經(jīng)對str指定了初始化值剖淀,
        // 構造器中不能對final變量重新賦值,下面賦值語句非法
        // str = "java";
        c = 5;
    }
    public void changeFinal()
    {
        // 普通方法不能為final修飾的成員變量賦值
        // d = 1.2;
        // 不能在普通方法中為final成員變量指定初始值
        // ch = 'a';
    }
    public static void main(String[] args)
    {
        FinalVariableTest ft = new FinalVariableTest();
        System.out.println(ft.a);
        System.out.println(ft.c);
        System.out.println(ft.d);
    }


}


假如打算在構造函數(shù)中纤房,初始塊中對final成員變量進行初始化纵隔,則不應在初始化之前直接訪問final成員變量

但Java又允許通過方法來訪問final成員變量,此時系統(tǒng)就會幫你將final成員變量進行默認初始化

public class FinalErrorTest {

    // 定義一個final修飾的實例變量
    // 系統(tǒng)不會對final成員變量進行默認初始化
    final int age;
    {
        // age沒有初始化炮姨,所以此處代碼將引起錯誤捌刮。
//      System.out.println(age);
        printAge();
        age = 6;
        System.out.println(age);
    }
    public void printAge(){
        System.out.println(age);
    }
    public static void main(String[] args)
    {
        new FinalErrorTest();
    }

    
}

final成員變量在顯式初始化之前不能直接訪問,但又可以通過方法來訪問舒岸,這可能是Java設計的一個缺陷

final局部變量

系統(tǒng)不會對局部變量進行初始化绅作,必須程序員自己進行顯式初始化

所以用final修飾局部變量,可以在定義同時指定初始值蛾派,也可以不指定

  • 如果定義時沒有指定初始值俄认,可以在后面進行初始化个少,但只能進行一次

  • 如果定義時已經(jīng)指定初始值,后面就不能再賦值


public class FinalLocalVariableTest {

    public void test(final int a)
    {
        // 不能對final修飾的形參賦值眯杏,下面語句非法
        // a = 5;
    }
    public static void main(String[] args)
    {
        // 定義final局部變量時指定默認值夜焦,則str變量無法重新賦值
        final String str = "hello";
        // 下面賦值語句非法
        // str = "Java";
        // 定義final局部變量時沒有指定默認值,則d變量可被賦值一次
        final double d;
        // 第一次賦初始值岂贩,成功
        d = 5.6;
        // 對final變量重復賦值茫经,下面語句非法
        // d = 3.4;
    }

    
}

final修飾基本類型變量和引用類型變量

  • final修飾基本類型變量,不能對該變量重新賦值

  • final修飾引用類型變量萎津,final只保證這個變量所引用的地址不變卸伞,即一直引用同一個對象,但是這個對象是可以改變的

class Person
{
    private int age;
    public Person(){}
    // 有參數(shù)的構造器
    public Person(int age)
    {
        this.age = age;
    }
    // 省略age的setter和getter方法
    // age的setter和getter方法
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getAge()
    {
        return this.age;
    }
}
public class FinalReferenceTest
{
    public static void main(String[] args)
    {
        // final修飾數(shù)組變量姜性,iArr是一個引用變量
        final int[] iArr = {5, 6, 12, 9};
        System.out.println(Arrays.toString(iArr));
        // 對數(shù)組元素進行排序瞪慧,合法
        Arrays.sort(iArr);
        System.out.println(Arrays.toString(iArr));
        // 對數(shù)組元素賦值,合法
        iArr[2] = -8;
        System.out.println(Arrays.toString(iArr));
        // 下面語句對iArr重新賦值部念,非法
        // iArr = null;
        // final修飾Person變量弃酌,p是一個引用變量
        final Person p = new Person(45);
        // 改變Person對象的age實例變量,合法
        p.setAge(23);
        System.out.println(p.getAge());
        // 下面語句對p重新賦值儡炼,非法
        // p = null;
    }
}


"宏替換"final變量

當變量滿足三個條件時妓湘,這個final變量就不再是一個變量,而是一個直接量:

  • final修飾符修飾

  • 在定義時就指定了初始值

  • 該初始值可以在編譯時就被確定

public class FinalLocalTest {

    public static void main(String[] args) {
        final int a = 5;

        System.out.println(a);
    }
}

System.out.println(a)語句實際上是直接執(zhí)行 System.out.println(5)

如果被賦值的表達式只是基本的算術表達式或字符串連接操作乌询,沒有訪問普通變量以及調用方法榜贴,Java編譯器同樣將這種final變量當做“宏變量”處理


public class FinalReplaceTest {


    public static void main(String[] args)
    {
        // 下面定義了4個final“宏變量”
        final int a = 5 + 2;
        final double b = 1.2 / 3;
        final String str = "leran" + "Java";
        final String book = "Java" + 99.0;
        // 下面的book2變量的值因為調用了方法,所以無法在編譯時被確定下來
        final String book2 = "Java" + String.valueOf(99.0);  //①
        System.out.println(book == "Java99.0");
        System.out.println(book2 == "Java99.0");
    }


}

再看一個例子:

public class StringJoinTest {

    public static void main(String[] args)
    {
        String s1 = "LJava";
        // s2變量引用的字符串可以編譯時就確定出來妹田,
        // 因此s2直接引用常量池中已有的"LJava"字符串
        String s2 = "L" + "Java";
        System.out.println(s1 == s2); // 輸出true
        // 定義2個字符串直接量
        String str1 = "L";     //①
        String str2 = "Java";     //②
        // 將str1和str2進行連接運算
        String s3 = str1 + str2;
        System.out.println(s1 == s3); // 輸出false
    }
}

final方法

final修飾的方法不可重寫

public class FinalMethodTest
{
    public final void test(){}
}
class Sub extends FinalMethodTest
{
    // 下面方法定義將出現(xiàn)編譯錯誤唬党,不能重寫final方法
//    public void test(){}
}

final類

final修飾的類不可以有子類

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鬼佣,隨后出現(xiàn)的幾起案子驶拱,更是在濱河造成了極大的恐慌,老刑警劉巖晶衷,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓝纲,死亡現(xiàn)場離奇詭異,居然都是意外死亡晌纫,警方通過查閱死者的電腦和手機税迷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锹漱,“玉大人箭养,你說我怎么就攤上這事×枋撸” “怎么了露懒?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵闯冷,是天一觀的道長。 經(jīng)常有香客問我懈词,道長蛇耀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任坎弯,我火速辦了婚禮纺涤,結果婚禮上,老公的妹妹穿的比我還像新娘抠忘。我一直安慰自己撩炊,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布崎脉。 她就那樣靜靜地躺著拧咳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪囚灼。 梳的紋絲不亂的頭發(fā)上骆膝,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音灶体,去河邊找鬼阅签。 笑死,一個胖子當著我的面吹牛蝎抽,可吹牛的內容都是我干的政钟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼樟结,長吁一口氣:“原來是場噩夢啊……” “哼养交!你這毒婦竟也來了?” 一聲冷哼從身側響起瓢宦,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤层坠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后刁笙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡谦趣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年疲吸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片前鹅。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡摘悴,死狀恐怖,靈堂內的尸體忽然破棺而出舰绘,到底是詐尸還是另有隱情蹂喻,我是刑警寧澤葱椭,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站口四,受9級特大地震影響孵运,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蔓彩,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一治笨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赤嚼,春花似錦旷赖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹂空,卻和暖如春俯萌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腌闯。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工绳瘟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姿骏。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓糖声,卻偏偏與公主長得像,于是被迫代替她去往敵國和親分瘦。 傳聞我的和親對象是個殘疾皇子蘸泻,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容

  • 1. 含義 在不同使用場景下,有細微的區(qū)別,總體是指的是"這是不可變的" final的保留關鍵字,可以聲明成員變量...
    ting723閱讀 477評論 0 2
  • 在Java 中嘲玫,final關鍵字可以修飾 類悦施,方法,和變量(包含成員變量和局部變量)去团。 final 類 當用fin...
    伊凡的一天閱讀 243評論 0 2
  • 1.修飾類 用final修飾一個類時抡诞,表明這個類不能被繼承 final類中的所有成員方法都會被隱式地指定為fina...
    Sarahhhh閱讀 701評論 0 0
  • java中final關鍵字在平時開發(fā)中用到的不多也不算少,大多均用在修飾類的變量上土陪,很少用final去對一個類進行...
    打不開的回憶閱讀 1,078評論 1 50
  • 小綠車:2元 豆?jié){:2元 午飯:9元(盒飯)
    折草閱讀 123評論 0 0