日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】6.4 final 修饰符

發布時間:2025/3/20 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】6.4 final 修饰符 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

final?成員變量

final局部變量

?final修飾基本類型變量和引用類型變量的區別

可執行“宏替換”的final變量?

final方法

final類

不可變類

緩存實例的不可變類


【final】關鍵字可以用來修飾【類】、【變量】(包括成員變量和局部變量)、【方法】

final?成員變量

Java成員(Field)默認是可以由系統執行初始化,程序員可以不指定初始化。而final修飾過的成員變量【必須由程序員執行初始化】,final修飾變量 ——?該變量值只能賦值一次,不可改變。(原因見注釋1)

【注意】若final修飾實例變量,可以再如下三個地方為final實例變量的初始值 ——?最多指定一次,不能多也不能少

  • 定義時指定初始值
  • 初始化塊
  • 構造器
  • 【添加】普通方法不能為final修飾的成員變量賦值
  • 【添加】final不會對成員變量進行隱式初始化
  • 【注意】普通方法不能對final值修飾的實例變量賦值。若final修飾類變量,可以在如下2個地方為final類變量指定初始值

  • 定義時指定初始值
  • 類初始化
  • 實例變量不能在靜態初始化塊中指定初始值(原因見注釋2),同樣的類變量也不能在普通初始化塊中指定初始值

    public class FinalVariableTest {// 定義成員變量時的初始值,合法final int a = 6;// 下面變量將在初始化塊或構造器中分配初始值final String str;final int c;final static double d;// 以上既沒有指定默認值,有沒有在初始化塊或構造器中指定初始化值// 下面定義的ch實例變量是不合法的// final char ch;// 初始化塊,可對沒有指定默認值的實例變量指定初始化值{// 在初始化塊中為實例變量指定初始值str = "hello";}static {// 靜態初始化塊為靜態變量指定初始值d = 55.56;}// 構造器中,可對既有沒有默認初始值,又沒有在初始化塊中指定初始值的實例變量指定初始值public FinalVariableTest() {c = 5;}public void changeFinal() {// 普通方法不能為final修飾的變量賦值// 不能在普通方法中為final成員變量指定初始值// d=1.2;// ch='a';}public static void main(String[] args) {FinalVariableTest ft = new FinalVariableTest();System.out.println(ft.a); //輸出6System.out.println(ft.c); //輸出5System.out.println(ft.str); //輸出helloSystem.out.println(FinalVariableTest.d); //輸出55.56} }

    final局部變量

    系統不會對局部變量初始化,所以需要有程序員顯式初始化。在final修飾的局部變量中

  • 可以在定義時就賦值
  • 也可以在后面代碼中對final修飾的局部變量賦初始值
  • 且賦值之后不可改變
  • ?final修飾基本類型變量和引用類型變量的區別

    當使用final修飾基本類型變量的時候,基本類型變量只能被賦值一次。但是當final修飾引用類型變量的時候,他保存的僅僅只是一個引用,final只能保證這個引用變量的地址不會被改變,即一直引用同一個對象。使用final修飾的引用類型變量不能被重新賦值,但是可以改變引用類新變量所引用對象的內容

    import java.util.Arrays;class Persons{private int age;public Persons(){}public Persons(int age) {this.age=age;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} } public class FinalReferenceTest {public static void main(String[] args) {//final修飾數組變量,iArr是一個引用變量final int[] iArr = {5,6,8,2};System.out.println(Arrays.toString(iArr));//對數組元素進行排序,合法Arrays.sort(iArr);System.out.println(Arrays.toString(iArr));//對于元素賦值,合法iArr[2]=-8;System.out.println(Arrays.toString(iArr));//下面語句對iArr重新賦值,非法//iArr = null;//final修飾Person變量,p是一個引用變量final Persons p = new Persons(45);//改變Person對象的age值,合法p.setAge(23);System.out.println(p.getAge());//下面語句對p重新賦值,非法//p = null;} }

    運行結果

    可執行“宏替換”的final變量?

    final是在編譯的時候就確定下來了。只要有變量,編譯的時候就確定不下來。對于一個final變量來說,無論它是什么類型的變量,只要滿足以下三個條件,這個final就不再是一個變量,而是相當于一個直接量:

  • 使用final修飾符修飾
  • 在定義該final變量時指定了初始值
  • 該初始值可以在編譯時就被確定下來
  • final方法

    final修飾的方法不可被重寫,常用于不希望父類中的方法被子類重寫重寫。

    Java提供Object類中就有一個final方法:getClass()

    此外,在Java方法中,final和private一起使用時沒有意義(注釋3

    public class FinalMethonTest{private void test() {} } class Sub extends FinalVariableTest{//會出現提示性錯誤@Overrideprivate void test() {//} }

    final類

    final修飾的類不允許有子類。用于保護父類的內部數據和禁止重寫父類的方法。。

    不可變類

    不可變類是指創建該類的實例之后,該實例不可被改變。比如8個包裝類。?如果需要創建自定義的不可變類,需要遵守如下準則:

  • 使用private和final修飾符來修飾類的成員變量
  • 提供攜帶參數構造器,用于根據傳入參數來初始化類里的成員變量
  • 僅為該類的成員變量提供getter()方法,不要為成員變量提供setter方法,因為普通方法不能修改final修飾的成員變量的值
  • 若有必要,重寫Object類的hashCode()和equals()兩個方法。equals方法根據關鍵成員變量來作為兩個對象是否相等的標準,除此之外,還應該保證用兩個equals方法判斷為相等的hashCode方法也相等
  • class Name {private String firstName;private String lastName;public Name() {}public Name(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}}public class Person3 {private final Name name;public Person3(Name name) {// 設置name實例變量為臨時創建的Name對象,該對象為firstname和lastname// 與傳入的name參數的firstname和lastname相同this.name = new Name(name.getFirstName(),name.getLastName());//若換下面的語句,則可以對firstname做修改//this.name = name;}public Name getName() {return new Name(name.getFirstName(),name.getLastName());//return name;}public static void main(String[] args) {Name n = new Name("悟空", "孫");Person3 p = new Person3(n);// Person對象的name的firstname為:悟空System.out.println(p.getName().getFirstName());// 以下為了改變Person對象的firstname值//無法改變值了,輸出還是悟空n.setFirstName("八戒");System.out.println(p.getName().getFirstName());} }

    緩存實例的不可變類

    若經常使用不可變類,可以將不可變類緩存下來。

    class CacheImmutale{private static int MAX_SIZE=10;//用數組緩存已有實例private static CacheImmutale[] cache = new CacheImmutale[MAX_SIZE];//記錄緩存實例在緩存中的位置,cache[pos-1]是最新的緩存實例private static int pos = 0;private final String name;private CacheImmutale(String name) {this.name=name;}public String getName() {return name;}public static CacheImmutale valueOf(String name) {//遍歷已緩存對象for (int i = 0; i < MAX_SIZE; i++) {//若存在兩個相同的實例,則直接返回該緩存實例if(cache[i]!=null&&cache[i].getName().equals(name)) {return cache[i];}}//若緩存池已滿if(pos==MAX_SIZE) {//把緩存的第一個對象覆蓋,即把剛剛生成的對象放在緩存池最開始的位置cache[0]=new CacheImmutale(name);//把pos設為1pos=1;}else{cache[pos++]=new CacheImmutale(name);}return cache[pos-1];}public boolean equals(Object obj) {if(this==obj) {return true;}if(obj!=null&&obj.getClass()==CacheImmutale.class) {CacheImmutale ci= (CacheImmutale)obj;return name.equals(ci.getName());}return false;}public int hashCode() {return name.hashCode();}} public class CacheImmutaleTest {public static void main(String[] args) {CacheImmutale c1 = CacheImmutale.valueOf("hello");CacheImmutale c2 = CacheImmutale.valueOf("hello");System.out.println(c1==c2); //輸出true} }

    ?

    注釋1若讓系統初始化,變量則會被自動賦予0/0.0/\u0000/false/null等值。final修飾的這也變量值不允許被改變,name這些就失去價值了

    【注釋2】因為靜態初始化塊是靜態成員,不可以訪問實例變量 ——?非靜態成員。

    【注釋3】因為private方法不能被子類中的實例訪問到,所以子類中即使有相同的名字、相同的形參列表、相同的返回值,那也只不過是定義了一個新的方法,不是重寫。同時final也是不讓子類重寫方法,所以兩者放在一起沒有意義

    總結

    以上是生活随笔為你收集整理的【Java】6.4 final 修饰符的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。