首頁 Java Java基礎 java final關鍵字的作用是什麼

java final關鍵字的作用是什麼

Nov 25, 2022 pm 04:26 PM
java final

在java中,final可以用來修飾類別、方法和變數。 final修飾類,表示該類是無法被任何其他類繼承的,意味著此類在一個繼承樹中是一個葉子類,並且此類的設計已被認為很完美而不需要進行修改或擴展。 final修飾類別中的方法,表示該類別是無法被任何其他類別繼承的,不可以被重寫;也就是把該方法鎖定了,以防止繼承類別對其進行更改。 final修飾類別中的變量,表示該變數一旦被初始化就不可改變。

java final關鍵字的作用是什麼

本教學操作環境:windows7系統、java8版、DELL G3電腦。

final關鍵字是什麼?

1、final可以用來修飾的結構:類別、方法、變數

2、final用來修飾一個類別:此類不能被其它類別繼承。

當我們需要讓一個類別永遠不被繼承,此時就可以用final修飾,但要注意:final類別中所有的成員方法都會隱式的定義為final方法

例如:String類別、System類別、StringBuffer類別

3、final  用來修飾方法  :表示此方法無法重寫 

  • #作用

    (1) 把方法鎖定,以防止繼承類別對其進行更改。

    (2) 效率,在早期的java版本中,會將final方法轉為內嵌呼叫。但若方法過於龐大,可能在效能上不會有太大提升。因此在最近版本中,不需要final方法進行這些最佳化了。

    final方法意味著「最後的、最終的」意義,即此方法不能被重寫。

  • 例如:Object類別中的getClass( )

4、final 用來修飾變量,此時變數就相當於常數

  • final用來修飾屬性:可以考慮賦值的位置有:明確初始化、程式碼區塊中初始化、建構器中初始化

  • final修飾局部變數:尤其是使用final修飾形參時,表示此形參是常數。當我們呼叫此方法時,給常量形參賦一個實參,一旦賦值之後,就只能在方法體內使用此形參的值,不能重新進行賦值。

  • 如果final修飾一個引用型別時,則在對其初始化之後便不能再讓其指向其他物件了或者說他的位址不能改變了(因為引用的值是一個位址,final要求值,即地址的值不會改變),但該引用所指向的物件的內容是可以改變的。本質上是一回事。

5、使用final 關鍵字宣告類別、變數和方法需要注意以下幾點:

  • final 用在變數的前面表示變數的值不可以改變,此時變數可以稱為常數。

  • final 用在方法的前面表示方法不可以被重寫(子類別中如果建立了一個與父類別中相同名稱、相同傳回值類型、相同參數清單的方法,只是方法體中的實作不同,以實現不同於父類的功能,這種方式被稱為方法重寫,又稱為方法覆蓋。這裡了解即可,教程後面我們會詳細講解)。

  • final 用在類別的前面表示該類別不能有子類,即該類別不可以被繼承。

final 修飾變數

#final 修飾的變數即成為常數,只能賦值一次,但是final 所修飾局部變數和成員變數有所不同。

  • final 修飾的局部變數必須使用先前被賦值一次才能使用。

  • final 修飾的成員變數在宣告時沒有賦值的叫做「空白 final 變數」。空白 final 變數必須在建構方法或靜態程式碼區塊中初始化。

注意:final 修飾的變數不能被賦值這種說法是錯誤的,嚴格的說法是,final 修飾的變數不可被改變,一旦獲得了初始值,該final 變量的值就不能被重新賦值。

public class FinalDemo {
    void doSomething() {
        // 没有在声明的同时赋值
        final int e;
        // 只能赋值一次
        e = 100;
        System.out.print(e);
        // 声明的同时赋值
        final int f = 200;
    }
    // 实例常量
    final int a = 5; // 直接赋值
    final int b; // 空白final变量
    // 静态常量
    final static int c = 12;// 直接赋值
    final static int d; // 空白final变量
    // 静态代码块
    static {
        // 初始化静态变量
        d = 32;
    }
    // 构造方法
    FinalDemo() {
        // 初始化实例变量
        b = 3;
        // 第二次赋值,会发生编译错误
        // b = 4;
    }
}

上述程式碼第4 行和第6 行是宣告局部常數,其中第4 行只是宣告沒有賦值,但必須在使用之前賦值(見程式碼第6 行),其實局部常數最好在聲明的同時初始化。程式碼第 13、14、16 和 17 行都宣告成員常數。程式碼第 13 和 14 行是實例常數,如果是空白 final 變數(請參閱程式碼第 14 行),則需要在建構方法中初始化(請參閱程式碼第 27 行)。程式碼第 16 和 17 行是靜態常數,如果是空白 final 變數(請參閱程式碼第 17 行),則需要在靜態程式碼區塊中初始化(請參閱程式碼第 21 行)。

另外,無論是那種常數只能賦值一次,請參閱程式碼第 29 行為 b 常數賦值,因為之前 b 已經賦值過一次,因此這裡會發生編譯錯誤。

final 修飾基本型別變數與引用型別變數的差異

当使用 final 修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。 但对于引用类型变量而言,它保存的仅仅是一个引用,final 只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。

下面程序示范了 final 修饰数组和 Person 对象的情形。

import java.util.Arrays;
class Person {
    private int age;
    public Person() {
    }
    // 有参数的构造器
    public Person(int age) {
        this.age = age;
    }
    // 省略age的setter和getter方法
    // age 的 setter 和 getter 方法
}
public class FinalReferenceTest {
    public static void main(String[] args) {
        // final修饰数组变量,iArr是一个引用变量
        final int[] iArr = { 5, 6, 12, 9 };
        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 Person p = new Person(45);
        // 改变Person对象的age实例变量,合法
        p.setAge(23);
        System.out.println(p.getAge());
        // 下面语句对P重新赋值,非法
        // p = null;
    }
}

从上面程序中可以看出,使用 final 修饰的引用类型变量不能被重新赋值,但可以改变引用类型变量所引用对象的内容。例如上面 iArr 变量所引用的数组对象,final 修饰后的 iArr 变量不能被重新赋值,但 iArr 所引用数组的数组元素可以被改变。与此类似的是,p 变量也使用了 final 修饰,表明 p 变量不能被重新赋值,但 p 变量所引用 Person 对象的成员变量的值可以被改变。

注意:在使用 final 声明变量时,要求全部的字母大写,如 SEX,这点在开发中是非常重要的。

如果一个程序中的变量使用 public static final 声明,则此变量将称为全局变量,如下面的代码:

public static final String SEX= "女";

final修饰方法

final 修饰的方法不可被重写,如果出于某些原因,不希望子类重写父类的某个方法,则可以使用 final 修饰该方法。

Java 提供的 Object 类里就有一个 final 方法 getClass(),因为 Java 不希望任何类重写这个方法,所以使用 final 把这个方法密封起来。但对于该类提供的 toString() 和 equals() 方法,都允许子类重写,因此没有使用 final 修饰它们。

下面程序试图重写 final 方法,将会引发编译错误。

public class FinalMethodTest {
    public final void test() {
    }
}
class Sub extends FinalMethodTest {
    // 下面方法定义将出现编译错误,不能重写final方法
    public void test() {
    }
}

上面程序中父类是 FinalMethodTest,该类里定义的 test() 方法是一个 final 方法,如果其子类试图重写该方法,将会引发编译错误。

对于一个 private 方法,因为它仅在当前类中可见,其子类无法访问该方法,所以子类无法重写该方法——如果子类中定义一个与父类 private 方法有相同方法名、相同形参列表、相同返回值类型的方法,也不是方法重写,只是重新定义了一个新方法。因此,即使使用 final 修饰一个 private 访问权限的方法,依然可以在其子类中定义与该方法具有相同方法名、相同形参列表、相同返回值类型的方法。

下面程序示范了如何在子类中“重写”父类的 private final 方法。

public class PrivateFinalMethodTest {
    private final void test() {
    }
}
class Sub extends PrivateFinalMethodTest {
    // 下面的方法定义不会出现问题
    public void test() {
    }
}

上面程序没有任何问题,虽然子类和父类同样包含了同名的 void test() 方法,但子类并不是重写父类的方法,因此即使父类的 void test() 方法使用了 final 修饰,子类中依然可以定义 void test() 方法。

final 修饰的方法仅仅是不能被重写,并不是不能被重载,因此下面程序完全没有问题。

public class FinalOverload {
    // final 修饰的方法只是不能被重写,完全可以被重载
    public final void test(){}
    public final void test(String arg){}
}

final修饰类

final 修饰的类不能被继承。当子类继承父类时,将可以访问到父类内部数据,并可通过重写父类方法来改变父类方法的实现细节,这可能导致一些不安全的因素。为了保证某个类不可被继承,则可以使用 final 修饰这个类。

下面代码示范了 final 修饰的类不可被继承。

final class SuperClass {
}
class SubClass extends SuperClass {    //编译错误
}

因为 SuperClass 类是一个 final 类,而 SubClass 试图继承 SuperClass 类,这将会引起编译错误。

final 修饰符使用总结

1. final 修饰类中的变量

表示该变量一旦被初始化便不可改变,这里不可改变的意思对基本类型变量来说是其值不可变,而对对象引用类型变量来说其引用不可再变。其初始化可以在两个地方:一是其定义处,也就是说在 final 变量定义时直接给其赋值;二是在构造方法中。这两个地方只能选其一,要么在定义时给值,要么在构造方法中给值,不能同时既在定义时赋值,又在构造方法中赋予另外的值。

2. final 修饰类中的方法

说明这种方法提供的功能已经满足当前要求,不需要进行扩展,并且也不允许任何从此类继承的类来重写这种方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。在声明类中,一个 final 方法只被实现一次。

3. final 修饰类

表示该类是无法被任何其他类继承的,意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要进行修改或扩展。

對於 final 類別中的成員,可以定義其為 final,也可以不是 final。而對於方法,由於所屬類為 final 的關係,自然也就成了 final 型。也可以明確地為 final 類別中的方法加上一個 final,這顯然沒有意義。

推薦教學:《java教學

以上是java final關鍵字的作用是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java項目管理Maven的開發人員指南 Java項目管理Maven的開發人員指南 Jul 30, 2025 am 02:41 AM

Maven是Java項目管理和構建的標準工具,答案在於它通過pom.xml實現項目結構標準化、依賴管理、構建生命週期自動化和插件擴展;1.使用pom.xml定義groupId、artifactId、version和dependencies;2.掌握核心命令如mvnclean、compile、test、package、install和deploy;3.利用dependencyManagement和exclusions管理依賴版本與衝突;4.通過多模塊項目結構組織大型應用並由父POM統一管理;5.配

用雅加達EE在Java建立靜止的API 用雅加達EE在Java建立靜止的API Jul 30, 2025 am 03:05 AM

SetupaMaven/GradleprojectwithJAX-RSdependencieslikeJersey;2.CreateaRESTresourceusingannotationssuchas@Pathand@GET;3.ConfiguretheapplicationviaApplicationsubclassorweb.xml;4.AddJacksonforJSONbindingbyincludingjersey-media-json-jackson;5.DeploytoaJakar

Python物業裝飾示例 Python物業裝飾示例 Jul 30, 2025 am 02:17 AM

@property裝飾器用於將方法轉為屬性,實現屬性的讀取、設置和刪除控制。 1.基本用法:通過@property定義只讀屬性,如area根據radius計算並直接訪問;2.進階用法:使用@name.setter和@name.deleter實現屬性的賦值驗證與刪除操作;3.實際應用:在setter中進行數據驗證,如BankAccount確保餘額非負;4.命名規範:內部變量用_前綴,property方法名與屬性一致,通過property統一訪問控制,提升代碼安全性和可維護性。

CSS暗模式切換示例 CSS暗模式切換示例 Jul 30, 2025 am 05:28 AM

首先通過JavaScript獲取用戶系統偏好和本地存儲的主題設置,初始化頁面主題;1.HTML結構包含一個按鈕用於觸發主題切換;2.CSS使用:root定義亮色主題變量,.dark-mode類定義暗色主題變量,並通過var()應用這些變量;3.JavaScript檢測prefers-color-scheme並讀取localStorage決定初始主題;4.點擊按鈕時切換html元素上的dark-mode類,並將當前狀態保存至localStorage;5.所有顏色變化均帶有0.3秒過渡動畫,提升用戶

CSS下拉菜單示例 CSS下拉菜單示例 Jul 30, 2025 am 05:36 AM

是的,一個常見的CSS下拉菜單可以通過純HTML和CSS實現,無需JavaScript。 1.使用嵌套的ul和li構建菜單結構;2.通過:hover偽類控制下拉內容的顯示與隱藏;3.父級li設置position:relative,子菜單使用position:absolute進行定位;4.子菜單默認display:none,懸停時變為display:block;5.可通過嵌套實現多級下拉,結合transition添加淡入動畫,配合媒體查詢適配移動端,整個方案簡潔且無需JavaScript支持,適合大

在Java開發區塊鏈應用程序 在Java開發區塊鏈應用程序 Jul 30, 2025 am 12:43 AM

理解區塊鏈核心組件,包括區塊、哈希、鍊式結構、共識機制和不可篡改性;2.創建包含數據、時間戳、前一哈希和Nonce的Block類,並實現SHA-256哈希計算與工作量證明挖礦;3.構建Blockchain類管理區塊列表,初始化創世區塊,添加新區塊並驗證鏈的完整性;4.編寫主類測試區塊鏈,依次添加交易數據區塊並輸出鏈狀態;5.可選增強功能包括交易支持、P2P網絡、數字簽名、RESTAPI和數據持久化;6.可選用HyperledgerFabric、Web3J或Corda等Java區塊鏈庫進行生產級開

如何將Java MistageDigest用於哈希(MD5,SHA-256)? 如何將Java MistageDigest用於哈希(MD5,SHA-256)? Jul 30, 2025 am 02:58 AM

要使用Java生成哈希值,可通過MessageDigest類實現。 1.獲取指定算法的實例,如MD5或SHA-256;2.調用.update()方法傳入待加密數據;3.調用.digest()方法獲取哈希字節數組;4.將字節數組轉換為十六進製字符串以便讀取;對於大文件等輸入,應分塊讀取並多次調用.update();推薦使用SHA-256而非MD5或SHA-1以確保安全性。

Python Parse Date String示例 Python Parse Date String示例 Jul 30, 2025 am 03:32 AM

使用datetime.strptime()可將日期字符串轉換為datetime對象,1.基本用法:通過"%Y-%m-%d"解析"2023-10-05"為datetime對象;2.支持多種格式如"%m/%d/%Y"解析美式日期、"%d/%m/%Y"解析英式日期、"%b%d,%Y%I:%M%p"解析帶AM/PM的時間;3.可用dateutil.parser.parse()自動推斷未知格式;4.使用.d

See all articles