Jadual Kandungan
五、final原理
Rumah Java javaTutorial Java中final实现原理的深入分析(附示例)

Java中final实现原理的深入分析(附示例)

Nov 27, 2018 pm 04:56 PM
final

本篇文章给大家带来的内容是关于Java中final实现原理的深入分析(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。

一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

一、final变量

final成员变量表示常量,只能被赋值一次,赋值后值不再改变(final要求地址值不能改变)

当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。

final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。

二、final方法

使用final方法的原因有两个。

第一个原因是把方法锁定,以防任何继承类修改它的含义,不能被重写;

第二个原因是效率,final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。

(注:类的private方法会隐式地被指定为final方法)

三、final类

当用final修饰一个类时,表明这个类不能被继承。

final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。

四、final使用总结

final关键字的好处:

(1)final关键字提高了性能。JVM和Java应用都会缓存final变量。

(2)final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。

(3)使用final关键字,JVM会对方法、变量及类进行优化。

关于final的重要知识点

1、final关键字可以用于成员变量、本地变量、方法以及类。

2、final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。

3、你不能够对final变量再次赋值。

4、本地变量必须在声明时赋值。

5、在匿名类中所有变量都必须是final变量。

6、final方法不能被重写。

7、final类不能被继承。

8、final关键字不同于finally关键字,后者用于异常处理。

9、final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。

10、接口中声明的所有变量本身是final的。

11、final和abstract这两个关键字是反相关的,final类就不可能是abstract的。

12、final方法在编译阶段绑定,称为静态绑定(static binding)。

13、没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。

14、将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。

15、按照Java代码惯例,final变量就是常量,而且通常常量名要大写。

16、对于集合对象声明为final指的是引用不能被更改,但是你可以向其中增加,删除或者改变内容。

五、final原理

最好先理解java内存模型 Java并发(二):Java内存模型

对于final域,编译器和处理器要遵守两个重排序规则:

1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。

(先写入final变量,后调用该对象引用)

原因:编译器会在final域的写之后,插入一个StoreStore屏障

2.初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。

(先读对象的引用,后读final变量)

编译器会在读final域操作的前面插入一个LoadLoad屏障 

示例1:

public class FinalExample {
    int i; // 普通变量
    final int j; // final 变量
    static FinalExample obj;
    public void FinalExample() { // 构造函数
        i = 1; // 写普通域
        j = 2; // 写 final 域
    }
    public static void writer() { // 写线程 A 执行
        obj = new FinalExample();
    }
    public static void reader() { // 读线程 B 执行
        FinalExample object = obj; // 读对象引用
        int a = object.i; // 读普通域         a=1或者a=0或者直接报错i没有初始化
        int b = object.j; // 读 final域      b=2
    }
}
Salin selepas log masuk

第一种情况:写普通域的操作被编译器重排序到了构造函数之外

而写 final 域的操作,被写 final 域的重排序规则“限定”在了构造函数之内,读线程 B 正确的读取了 final 变量初始化之后的值。

写 final 域的重排序规则可以确保:在对象引用为任意线程可见之前,对象的 final 域已经被正确初始化过了,而普通域不具有这个保障。

第二种情况:读对象的普通域的操作被处理器重排序到读对象引用之前

而读 final 域的重排序规则会把读对象 final 域的操作“限定”在读对象引用之后,此时该 final 域已经被 A 线程初始化过了,这是一个正确的读取操作。

读 final 域的重排序规则可以确保:在读一个对象的 final 域之前,一定会先读包含这个 final 域的对象的引用。

示例2:如果 final 域是引用类型

对于引用类型,写 final 域的重排序规则对编译器和处理器增加了如下约束:

在构造函数内对一个 final 引用的对象的成员域的写入,与随后在构造函数外把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。

public class FinalReferenceExample {
    final int[] intArray; // final 是引用类型
    static FinalReferenceExample obj;
    public FinalReferenceExample() { // 构造函数
        intArray = new int[1]; // 1
        intArray[0] = 1; // 2
    }
    public static void writerOne() { // 写线程 A 执行
        obj = new FinalReferenceExample(); // 3
    }
    public static void writerTwo() { // 写线程 B 执行
        obj.intArray[0] = 2; // 4
    }
    public static void reader() { // 读线程 C 执行
        if (obj != null) { // 5
            int temp1 = obj.intArray[0]; // 6  temp1=1或者temp1=2,不可能等于0
        }
    }
}
Salin selepas log masuk

 假设首先线程 A 执行 writerOne() 方法,执行完后线程 B 执行 writerTwo() 方法,执行完后线程 C 执行 reader () 方法。

 

在上图中,1 是对 final 域的写入,2 是对这个 final 域引用的对象的成员域的写入,3 是把被构造的对象的引用赋值给某个引用变量。这里除了前面提到的 1 不能和 3 重排序外,2 和 3 也不能重排序。

JMM 可以确保读线程 C 至少能看到写线程 A 在构造函数中对 final 引用对象的成员域的写入。即 C 至少能看到数组下标 0 的值为 1。而写线程 B 对数组元素的写入,读线程 C 可能看的到,也可能看不到。JMM 不保证线程 B 的写入对读线程 C 可见,因为写线程 B 和读线程 C 之间存在数据竞争,此时的执行结果不可预知。

Atas ialah kandungan terperinci Java中final实现原理的深入分析(附示例). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Di Jawa, adakah mungkin untuk menentukan pemalar hanya menggunakan kata kunci akhir? Di Jawa, adakah mungkin untuk menentukan pemalar hanya menggunakan kata kunci akhir? Sep 20, 2023 pm 04:17 PM

Pembolehubah malar ialah pembolehubah yang nilainya tetap dan hanya satu salinan wujud dalam atur cara. Sebaik sahaja anda mengisytiharkan pembolehubah malar dan memberikan nilai kepadanya, anda tidak boleh menukar nilainya semula sepanjang program. Tidak seperti bahasa lain, Java tidak menyokong pemalar secara langsung. Walau bagaimanapun, anda masih boleh mencipta pemalar dengan mengisytiharkan pembolehubah statik dan muktamad. Statik - Sebaik sahaja anda mengisytiharkan pembolehubah statik, ia akan dimuatkan ke dalam memori pada masa penyusunan, iaitu hanya satu salinan akan tersedia. Akhir - Sebaik sahaja anda mengisytiharkan pembolehubah akhir, nilainya tidak boleh diubah suai. Oleh itu, anda boleh mencipta pemalar dalam Java dengan mengisytiharkan pembolehubah contoh sebagai statik dan muktamad. Contoh Demonstrasi classData{&am

Perbezaan antara final, finally, dan finalize di Jawa Perbezaan antara final, finally, dan finalize di Jawa Feb 19, 2024 pm 12:16 PM

Perbezaan antara muktamad, akhirnya, dan memuktamadkan dalam Java memerlukan contoh kod khusus Dalam pengaturcaraan Java, anda sering menemui tiga kata kunci muktamad, akhirnya, dan memuktamadkan Walaupun ia dieja sama, ia mempunyai makna dan penggunaan yang berbeza. Artikel ini akan menerangkan perbezaan antara ketiga-tiga kata kunci ini secara terperinci dan memberikan contoh kod untuk membantu pembaca memahami dengan lebih baik. 1. Kata kunci akhir Kata kunci akhir boleh digunakan untuk kelas, kaedah dan pembolehubah. Fungsinya adalah untuk membuat kelas yang diubah suai

Apakah fungsi kata kunci akhir java Apakah fungsi kata kunci akhir java Nov 25, 2022 pm 04:26 PM

Di Java, final boleh digunakan untuk mengubah suai kelas, kaedah dan pembolehubah. Kelas diubah suai akhir bermakna kelas itu tidak boleh diwarisi oleh mana-mana kelas lain, yang bermaksud bahawa kelas ini ialah kelas daun dalam pokok warisan, dan reka bentuk kelas ini telah dianggap sempurna dan tidak perlu diubah suai atau dilanjutkan. Kaedah dalam kelas diubah suai akhir bermakna kelas itu tidak boleh diwarisi oleh mana-mana kelas lain dan tidak boleh ditindih iaitu kaedah dikunci untuk menghalang kelas yang diwarisi daripada mengubahnya. final mengubah suai pembolehubah dalam kelas, menunjukkan bahawa pembolehubah tidak boleh diubah setelah ia dimulakan.

Bagaimanakah objek akhir dibuat di Jawa? Bagaimanakah objek akhir dibuat di Jawa? Apr 11, 2024 pm 02:00 PM

Terdapat dua cara untuk mencipta objek akhir dalam Java: mengisytiharkan pembolehubah akhir atau mengisytiharkan kelas menggunakan pengubahsuai akhir. Apabila pembolehubah akhir diisytiharkan, objek dicipta melalui pemula apabila kelas akhir diisytiharkan, contoh kelas tidak boleh diubah. Yang penting, rujukan kepada objek akhir masih boleh berubah, tetapi objek yang mereka tunjuk tidak boleh berubah.

Ralat Java: Penyalahgunaan kata kunci akhir, cara menyelesaikan dan mengelakkannya Ralat Java: Penyalahgunaan kata kunci akhir, cara menyelesaikan dan mengelakkannya Jun 24, 2023 pm 09:00 PM

Sebagai bahasa pengaturcaraan yang sangat popular, Java digunakan secara meluas dalam Internet, peranti mudah alih dan bidang lain. Bagi pembangun Java, mereka sering menghadapi beberapa ralat atau masalah, salah satunya ialah penyalahgunaan kata kunci akhir. Di Java, kata kunci akhir sering digunakan untuk mengubah suai pembolehubah, kaedah, kelas, dll. Ini menunjukkan bahawa atribut tidak boleh diubah selepas ia ditakrifkan. Kata kunci akhir boleh membantu pembangun memastikan ketidakbolehubah objek dan mengelakkan masalah seperti keadaan perlumbaan, tetapi penyalahgunaan kata kunci akhir

Sintaks khas dalam PHP: Statik, Akhir, Abstrak dan kata kunci lain Sintaks khas dalam PHP: Statik, Akhir, Abstrak dan kata kunci lain May 11, 2023 pm 04:00 PM

PHP ialah bahasa skrip sebelah pelayan sumber terbuka yang popular digunakan secara meluas dalam pembangunan web. Bahasa PHP bukan sahaja mudah dipelajari dan digunakan, tetapi juga menyokong pelbagai paradigma pengaturcaraan, pengaturcaraan berorientasikan objek, pengaturcaraan berfungsi, dll. Dalam PHP, terdapat beberapa kata kunci sintaks khas, seperti Statik, Akhir, Abstrak, dll. Kata kunci ini mempunyai fungsi khas dalam pengaturcaraan berorientasikan objek. Artikel ini akan memperkenalkan kata kunci ini secara terperinci. Kata kunci statik Dalam PHP, kata kunci Statik mempunyai dua kegunaan

Mengapa pembina tidak boleh menjadi muktamad di Jawa? Mengapa pembina tidak boleh menjadi muktamad di Jawa? Aug 20, 2023 pm 07:01 PM

Setiap kali anda mengisytiharkan kaedah sebagai muktamad, anda tidak boleh mengatasinya. Iaitu, anda tidak boleh menyediakan subkelas dengan pelaksanaan kaedah akhir superclass. Maksudnya, tujuan pengisytiharan kaedah sebagai muktamad adalah untuk mengelakkan pengubahsuaian kaedah dari luar (subkelas). Dalam warisan, apabila anda melanjutkan kelas, subkelas mewarisi semua ahli superclass kecuali pembina. Dalam erti kata lain, pembina tidak boleh diwarisi di Jawa, oleh itu anda tidak boleh mengatasi pembina. Oleh itu, tidak ada gunanya meletakkan awalan pembina dengan akhir. Oleh itu, Java tidak membenarkan penggunaan kata kunci akhir sebelum pembina. Jika anda cuba mengisytiharkan pembina muktamad, ralat masa kompilasi akan dihasilkan mengatakan "modifierf

Perbandingan Akhir vs Keabadian di Jawa Perbandingan Akhir vs Keabadian di Jawa Aug 26, 2023 pm 09:37 PM

Kata kunci "akhir" dalam Java boleh digunakan untuk mentakrifkan nilai malar dan menghalang pembolehubah, kaedah, atau kelas daripada diubah atau ditindih. Kebolehubahan, sebaliknya, menerangkan ciri objek yang kekal dalam keadaan malar sepanjang kewujudannya. Sebaik sahaja objek terbentuk, nilainya tidak berubah. Pembolehubah, kaedah dan kelas dihadkan oleh kata kunci "akhir", tetapi kebolehubahan melangkah lebih jauh dan memastikan keseluruhan keadaan objek dipelihara. Marilah kita memahami perbezaan utama antara muktamad dan tidak berubah dalam artikel ini. Kata kunci akhir dalam Java Edisi Akhir Java mempunyai beberapa ciri: Pembolehubah akhir: Nilai awalnya tidak boleh diubah suai selepas pemulaan. Ia sering digunakan untuk mengisytiharkan nilai yang tidak boleh diubah atau tidak berubah. Kaedah akhir: Mereka tidak boleh diubah suai oleh subkelas, memastikan bahawa mereka berkelakuan secara konsisten. mereka membantu

See all articles