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

Java 中 final 关键字的奥秘

目录

一、final 修饰类:封印的 “永恒之石”

二、final 修饰变量:锁定的 “不变之值”

三、final 修饰方法:不可撼动的 “坚固堡垒”

四、总结


在 Java 编程的世界里,final 关键字就像一把神奇的 “锁”,一旦使用,就能赋予类、变量和方法独特的性质。今天,就让我们一同深入探究 final 关键字修饰类、变量和方法时的各种表现和用途,通过丰富的代码示例,感受它为我们的编程带来的便利与保障。

一、final 修饰类:封印的 “永恒之石”

当 final 关键字修饰一个类时,这个类就如同被封印的 “永恒之石”,无法被其他类继承。这意味着该类的设计和功能已经固定,不希望被修改或扩展。在实际应用中,这样的类通常用于表示那些具有特定用途、不需要也不应该被改变的实体。

比如,Java 标准库中的String类就是一个被 final 修饰的类。String类用于处理字符串,它的内部实现已经非常完善,并且在各种场景下都被广泛使用。如果允许其他类继承String类,可能会破坏String类的一些特性和安全性。

下面我们通过自定义一个被 final 修饰的类来加深理解:

final class ImmutablePoint {private int x;private int y;public ImmutablePoint(int x, int y) {this.x = x;this.y = y;}public int getX() {return x;}public int getY() {return y;}
}

在这个例子中,ImmutablePoint类被 final 修饰,它表示一个不可变的点。由于不能被继承,我们可以确保这个类的行为和属性不会被意外修改。如果尝试创建一个继承自ImmutablePoint的类,将会导致编译错误:

// 以下代码会导致编译错误,因为ImmutablePoint类被final修饰,不能被继承
// class SubImmutablePoint extends ImmutablePoint {
//     // 类体
// }

final 修饰类在保证代码的稳定性和安全性方面具有重要意义,尤其在一些基础类库的设计中,能防止子类对核心功能的破坏。

二、final 修饰变量:锁定的 “不变之值”

  1. final 修饰基本数据类型变量
    当 final 修饰基本数据类型变量时,该变量就成为一个常量,一旦被赋值,其值就不能再被改变。这在很多场景下非常有用,比如定义数学常量、配置参数等。

public class MathConstants {public static final double PI = 3.141592653589793;public static final int E = 2.71828;public static void main(String[] args) {// 以下代码会导致编译错误,因为PI是final修饰的常量,不能被重新赋值// PI = 3.14;System.out.println("圆周率PI的值为: " + PI);System.out.println("自然常数E的值为: " + E);}
}

在这个例子中,PIE都是被 final 修饰的常量,它们的值在程序运行过程中始终保持不变。使用 final 修饰常量,不仅可以提高代码的可读性,还能避免因意外赋值导致的错误。
2. final 修饰引用数据类型变量
当 final 修饰引用数据类型变量时,它表示该变量的引用不能再指向其他对象,但对象本身的内容是可以修改的。这一点需要特别注意,与基本数据类型变量有所不同。

class MutableObject {private int value;public MutableObject(int value) {this.value = value;}public void setValue(int value) {this.value = value;}public int getValue() {return value;}
}public class FinalReferenceExample {public static void main(String[] args) {final MutableObject obj = new MutableObject(10);// 以下代码会导致编译错误,因为obj是final修饰的变量,不能再指向其他对象// obj = new MutableObject(20);obj.setValue(30);System.out.println("对象的值为: " + obj.getValue());}
}

在这个例子中,obj是一个被 final 修饰的引用变量,它只能指向创建时的MutableObject对象,不能再指向其他对象。但是,我们可以通过调用对象的方法修改对象内部的状态,如obj.setValue(30)

三、final 修饰方法:不可撼动的 “坚固堡垒”

当 final 修饰一个方法时,该方法就不能被其子类重写。这在设计类的方法时非常有用,如果你希望某个方法的实现是固定的,不希望子类对其进行修改,可以将该方法声明为 final。

class Animal {public final void makeSound() {System.out.println("动物发出声音");}
}class Dog extends Animal {// 以下代码会导致编译错误,因为makeSound方法在父类中被final修饰,不能被重写// @Override// public void makeSound() {//     System.out.println("汪汪汪");// }
}

在这个例子中,Animal类中的makeSound方法被 final 修饰,Dog类作为Animal类的子类,不能重写makeSound方法。这确保了在继承体系中,makeSound方法的行为始终保持一致。

final 修饰方法在很多情况下可以提高程序的安全性和稳定性。例如,在一些核心算法的实现中,将关键方法声明为 final,可以防止子类无意中修改算法逻辑,导致程序出现错误。

四、总结

通过以上对 final 关键字修饰类、变量和方法的深入探讨,我们可以看到 final 关键字在 Java 编程中扮演着重要的角色。它为我们提供了一种机制,能够确保类的设计、变量的值以及方法的实现保持稳定和不变。合理使用 final 关键字,可以使我们的代码更加健壮、安全和易于维护。在实际编程中,我们需要根据具体的业务需求和设计目标,灵活运用 final 关键字,发挥它的最大优势。希望大家在今后的 Java 编程中,能够熟练掌握和运用 final 关键字,创造出更加优秀的程序。如果在学习过程中遇到任何问题,欢迎随时与我交流,让我们一起在 Java 编程的道路上不断前行。

相关文章:

Java 中 final 关键字的奥秘

目录 一、final 修饰类:封印的 “永恒之石” 二、final 修饰变量:锁定的 “不变之值” 三、final 修饰方法:不可撼动的 “坚固堡垒” 四、总结 在 Java 编程的世界里,final 关键字就像一把神奇的 “锁”,一旦使用&…...

C# 通用缓存类开发:开启高效编程之门

引言 嘿,各位 C# 开发者们!在当今快节奏的软件开发领域,提升应用程序的性能就如同给跑车装上涡轮增压,能让你的项目在激烈的竞争中脱颖而出。而构建一个高效的 C# 通用缓存类,无疑是实现这一目标的强大武器。 想象一…...

电脑办公技巧之如何在 Word 文档中添加文字或图片水印

Microsoft Word是全球最广泛使用的文字处理软件之一,它为用户提供了丰富的编辑功能来美化和保护文档。其中,“水印”是一种特别有用的功能,它可以用于标识文档状态(如“草稿”或“机密”)、公司标志或是版权信息等。本…...

记录一下OpenCV Contrib 编译踩的坑

最近有需要采用OpenCV Contrib 里面的函数做一下处理,要重新编译,一路编译两三个小时了,记录一下备忘吧。 1、编译前先准备好如下环境 ①visual studio已安装,具体版本和型号根据需求经验来,我看常用的是VS2015、VS201…...

01.04、回文排序

01.04、[简单] 回文排序 1、题目描述 给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。 2、解题思路 回文串的特点: 一个回文串在…...

[创业之路-259]:《向流程设计要效率》-1-让成功成熟业务交给流程进行复制, 把创新产品新业务新客户交给精英和牛人进行探索与创造

标题:成功与创新的双轨并行:以流程复制成熟,以精英驱动新知 在当今这个日新月异的商业环境中,企业要想持续繁荣发展,就必须在稳定与创新之间找到完美的平衡点。一方面,成熟业务的稳定运营是企业生存和发展的…...

如何使用usememo和usecallback进行性能优化,什么时候使用usecallback,什么时候使用usememo

React useMemo 和 useCallback 性能优化总结以及使用场景 基本概念 useMemo 用于缓存计算结果,避免在每次渲染时重复进行昂贵的计算。 useCallback 用于缓存函数引用,避免在每次渲染时创建新的函数引用。 使用时机对比 useMemo 适用场景 复杂计算…...

22. C语言 输入与输出详解

本章目录: 前言1. 输入输出的基础概念1.1 标准输入输出流1.2 输入输出函数 2. 格式化输出与输入2.1 使用 printf() 进行输出示例 1: 输出字符串示例 2: 输出整数示例 3: 输出浮点数 2.2 使用 scanf() 进行输入示例 4: 读取整数和字符改进方案:使用getchar()清理缓冲…...

WPF实战案例 | C# WPF实现计算器源码

WPF实战案例 | C# WPF实现计算器源码 一、设计来源计算器应用程序讲解1.1 主界面1.2 计算界面 二、效果和源码2.1 界面设计(XAML)2.2 代码逻辑(C#)2.3 实现步骤总结 源码下载更多优质源码分享 作者:xcLeigh 文章地址&a…...

AutoGen入门——快速实现多角色、多用户、多智能体对话系统

1.前言 如https://github.com/microsoft/autogen所述,autogen是一多智能体的框架,属于微软旗下的产品。 依靠AutoGen我们可以快速构建出一个多智能体应用,以满足我们各种业务场景。 本文将以几个示例场景,使用AutoGen快速构建出…...

LeetCode 热题 100_全排列(55_46_中等_C++)(递归(回溯))

LeetCode 热题 100_两数之和(55_46) 题目描述:输入输出样例:题解:解题思路:思路一(递归(回溯)): 代码实现代码实现(思路一&#xff08…...

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1.标准版)

问题 项目里使用了 AzureBlob 存储了用户上传的各种资源文件,近期 AzureBlob 的流量费用增长很快,想通过分析Blob的日志,获取一些可用的信息,所以有了这个需求:将存储账户的日志(读写,审计&…...

pthread_exit函数

pthread_exit 是 POSIX 线程库(pthread)中的一个函数,用于显式地终止调用线程。与 exit 函数不同,pthread_exit 仅影响调用它的线程,而不是整个进程。使用 pthread_exit 可以确保线程在退出时能够正确地释放线程相关的…...

1月21日星期二今日早报简报微语报早读

1月21日星期二,农历腊月廿二,早报#微语早读。 1、多地官宣:2025年可有序、限时或在限定区域燃放烟花爆竹; 2、TikTok恢复在美服务;特朗普提出继续运营TikTok方案,外交部:若涉及收购中国企业应…...

【2024年终总结】我与CSDN的一年

👉作者主页:心疼你的一切 👉作者简介:大家好,我是心疼你的一切。Unity3D领域新星创作者🏆,华为云享专家🏆 👉记得点赞 👍 收藏 ⭐爱你们,么么哒 文章目录 …...

openssl 正确生成v3带SAN的证书

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

Golang Gin系列-5:数据模型和数据库

在这篇Gin教程的博客中,我们将探索如何将模型和数据库与Gin框架无缝集成,使你能够构建健壮且可扩展的web应用程序。通过利用流行的库并遵循最佳实践,你将学习如何定义模型、建立数据库连接、执行CRUD操作以及确保基于gin的项目中的数据完整性…...

比简单工厂更好的 - 工厂方法模式(Factory Method Pattern)

工厂方法模式(Factory Method Pattern) 工厂方法模式(Factory Method Pattern)工厂方法模式(Factory Method Pattern)概述工厂方法模式(Factory Method Pattern)结构图工厂方法模式&…...

分布式搜索引擎02

1. DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1. DSL查询分类 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据&#xff0c…...

阿里云安装mikrotik7配置内网互通

阿里云近期推出了200M不限量机器,对于没有公网接入的中小企业可以借助这个机器对多地分支机构进行内网互通。目前已经有很多机构用这个搞跨云k8s,跨云集群了。 mikrotik作为一个商用的软件,操作性比一些开源的软件好用不少。 本文使用的网段为172.16.1…...

从Java的Jvm的角度解释一下为什么String不可变?

从Java的Jvm的角度解释一下为什么String不可变? 从 JVM 的角度看,Java 中 String 的不可变性是由多层次的机制共同保障的,这些设计涉及内存管理、性能优化和安全保障: 1. JVM 内存模型与字符串常量池 字符串常量池(St…...

历年西安交通大学计算机保研上机真题

2025西安交通大学计算机保研上机真题 2024西安交通大学计算机保研上机真题 2023西安交通大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school 计算圆周率近似值 题目描述 根据公式 π / 4 1 − 1 / 3 1 / 5 − 1 / 7 … \pi / 4 1 - 1/3 1/5 - …...

日志技术-LogBack、Logback快速入门、Logback配置文件、Logback日志级别

一. 日志技术 1. 程序中的日志,是用来记录应用程序的运行信息、状态信息、错误信息等。 2. JUL:(java.util.logging)这是JavaSE平台提供的官方日志框架,也被称为JUL。配置相对简单,但不够灵活,性能较差。 3.Logs4j&…...

山海鲸轻 3D 渲染技术深度解析:预渲染如何突破多终端性能瓶颈

在前期课程中,我们已系统讲解了山海鲸两大核心渲染模式——云渲染与端渲染的技术特性及配置方法。为满足复杂场景下的差异化需求,山海鲸创新推出轻3D渲染功能,本文将深度解析该技术的实现原理与操作实践。 一、轻3D功能研发背景 针对多终端协…...

华为FreeArc能和其他华为产品共用充电线吗?

最近刚买的FreeArc终于到手啦,看到网上有朋友说,这次的耳机是不附带充电线,开箱后发现果真如此,那FreeArc到底用什么规格的充电线,能不能和华为的Type-C数据线通用,我来给大家解答一下吧! Free…...

Linux操作系统 使用共享内存实现进程通信和同步

共享内存使用 //main.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <sys/shm.h> #include <string.h> int main() {int shmidshmget((key_t)1234,256,IPC_CREAT|0600);assert(shmid!-1);…...

人工智能100问☞第36问:什么是BERT?

目录 一、通俗解释 二、专业解析 三、权威参考 BERT是基于Transformer Encoder的双向语言预训练模型,具备强大的语义理解能力,是现代自然语言处理的重要基石。它是一套让机器像人一样“前后一起看”的语言理解技术,它让AI不光“读得快”,还“读得懂”。现在很多搜索引擎…...

引领机器人交互未来!MANUS数据手套解锁精准手部追踪

MANUS数据手套为机器人技术带来高精度手部追踪&#xff0c;助力实现人与机器的自然交互&#xff01;近年&#xff0c;越来越多客户希望利用这项技术精准操控机械臂、灵巧手和人形机器人&#xff0c;不断提升设备的智能化水平和交互体验。 MANUS数据手套是高精度人机交互设备&am…...

知识课堂|sCMOS相机可编程快门模式解析

sCMOS相机凭借高灵敏度、高动态、低读出噪声特性&#xff0c;成为生命科学成像领域的核心设备。在光片荧光显微镜LSFM成像应用中&#xff0c;传统卷帘快门的时序限制可能引发运动伪影或光片照明不均匀问题。可编程快门模式通过精确控制传感器曝光时序&#xff0c;实现与激光扫描…...

【Kubernetes】ubuntu20.04通过kubeadm + Docker安装k8s

Kubernetes v1.24集群安装配置步骤总结 一、环境准备 &#xff08;一&#xff09;系统要求 运行兼容deb/rpm的Linux操作系统&#xff08;如Ubuntu或CentOS&#xff09;的计算机&#xff0c;1台或多台。每台机器内存2GB以上&#xff0c;内存不足会限制应用运行。控制平面节点…...