当前位置: 首页 > news >正文

问:Java中final关键字有哪些用法和作用?

final 关键字在 Java 中确实是一个重要且常用的概念,理解它对掌握 Java 语言特性很有帮助。笔者基于这篇内容,说明 final 的作用与用法,并解释编译器对 final 域的重排序规则。

1. 被 final 修饰的类不可以被继承

public final class FinalClass {// Class body
}// 编译错误:无法继承 final 类
// public class SubClass extends FinalClass {
// }

2. 被 final 修饰的方法不可以被重写

public class ParentClass {public final void finalMethod() {System.out.println("This is a final method.");}
}public class ChildClass extends ParentClass {// 编译错误:无法重写 final 方法// public void finalMethod() {//     System.out.println("Attempt to override final method.");// }
}

3. 被 final 修饰的变量不可以被改变。如果修饰引用,那么表示引用不可变,引用指向的内容可变。

public class FinalVariableExample {public static void main(String[] args) {final int finalPrimitive = 10;// 编译错误:无法更改 final 变量的值// finalPrimitive = 20;final StringBuilder finalReference = new StringBuilder("Hello");// 合法:final 引用指向的对象内容可以更改finalReference.append(" World");System.out.println(finalReference); // 输出:Hello World// 编译错误:final 引用不能指向新的对象// finalReference = new StringBuilder("New String");}
}

4. 被 final 修饰的方法,JVM 会尝试将其内联,以提高运行效率

内联优化是由 JVM 在运行时决定的。可以理解为一个 final 方法会在编译期被认为是稳定的,JVM 有可能会将其调用替换为方法体,以减少方法调用的开销。

public class FinalMethodExample {public final void inlineMethod() {System.out.println("This method might be inlined by JVM.");}public static void main(String[] args) {FinalMethodExample example = new FinalMethodExample();for (int i = 0; i < 1000; i++) {example.inlineMethod(); // JVM 可能会内联此方法调用}}
}

5. 被 final 修饰的常量,在编译阶段会存入常量池中

当 final 修饰基本数据类型或 String 类型,并且在编译时就能确定其值时,该值会被编译器存入常量池中。

public class FinalConstantExample {public static final int CONSTANT_VALUE = 100;public static final String CONSTANT_STRING = "FINAL_STRING";public static void main(String[] args) {// 使用常量池中的值System.out.println(CONSTANT_VALUE);System.out.println(CONSTANT_STRING);}
}

编译器对 final 域的重排序规则

规则 1:在构造函数内对一个 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序
public class FinalFieldExample {private final int finalField;public FinalFieldExample(int value) {finalField = value; // 写入 final 域}public static void main(String[] args) {FinalFieldExample example = new FinalFieldExample(42);// 在构造函数返回前,finalField 必须已经被初始化System.out.println(example.finalField); // 输出:42}
}
规则 2:初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序
public class FinalFieldInitialization {private final int finalField;public FinalFieldInitialization() {// 经过构造函数后,finalField 已经被初始化finalField = initializeField();}private int initializeField() {return 42;}public int getFinalField() {return finalField;}public static void main(String[] args) {FinalFieldInitialization example = new FinalFieldInitialization();// 确保在读取 finalField 前,对象的引用已经被正确初始化System.out.println(example.getFinalField()); // 输出:42}
}

通过这些代码示例,我们可以更清楚地理解 final 关键字在 Java 中的作用及其多种用法。掌握这些用法,有助于我们编写更健壮的代码。


http://www.mrgr.cn/news/34770.html

相关文章:

  • 新手教学系列——善用 VSCode 工作区,让开发更高效
  • 传奇996_19——龙岭总结
  • FASTLIO2建图学习笔记
  • 搜维尔科技:Manus VR数据手套集成,遥操作五指灵巧手解决方案
  • 数字字符串格式化
  • D3的竞品有哪些,D3的优势,D3和echarts的对比
  • uniapp js怎么根据map需要显示的点位,计算自适应的缩放scale
  • 彻底删除国际版OneDrive for Business上的数据
  • es6常用知识汇总
  • ES6中迭代器与生成器知识浅析
  • C语言 | Leetcode C语言题解之第433题最小基因变化
  • 如何在Java后端中实现弹性伸缩:从线程池到容器化的完整指南
  • 手势手语识别数据集,YOLOv5目标检测两个数据集,图大量,模型精度高分别为近100类
  • vue2知识汇总
  • 【vue-media-upload 升级玩法】一个页面用两个Uploader,一个上传图片,一个上传视频(分开传,容易分开设置和展示图片和视频)
  • 库仑定律-库仑力-两个电荷之间静电力的计算公式
  • fo-dicom是如何实现DICOM 的网络通信功能
  • 远程升级,你成功了吗?
  • 【漏洞复现】HIKVISION 视频编码设备接入网关 showFile.php 任意文件下载漏洞
  • 解决方案:TypeError:float() argument must be a string or a number,not “NoneType”
  • OmniPeek 空口抓包软件安装指导
  • vue3知识汇总
  • 扩大产品库存怎么破?手把手教你,全开源哦!
  • JavaScript 是一种令人着迷但也充满争议的编程语言
  • 综合题第二题(路由器的配置)
  • PhpStudy —— README