深入解析final关键字的用法

夫陶公清风千古,余又何人,敢称庶几
在这里插入图片描述
个人博客地址:http://blog.breez.work


文章目录

  • 介绍
    • 解析
      • final属性
      • final方法
      • final参数
      • final类

介绍

final用于声明属性【属性不可变】、方法【方法不可覆盖】、(除了抽象类)【类不可被继承】

解析

final属性

被final修饰的变量不可变。【引用不可变

public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello");s.append(" World");System.out.println(s); //输出Hello World}
}

public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello World");s = new StringBuffer("Hello world"); //编译报错}
}

从上面可以看出final指的是引用不可变,即它只能指向初始化时指向的那个对象,不关心指向对象内容的变化。所以被final修饰的变量必须被初始化。

如何初始化:

  1. 在定义的时候初始化
final String name="BreezAm";
name="change"; //编译错误
  1. final成员变量可以在初始块中初始化,但不可在静态块中初始化。
  • 在初始化块中初始化:【编译通过
public class FinalTest {private final String name;//定义一个成员变量{name = "BreezAm";//初始化块中初始化成员变量name}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAmtest.name="change";//编译报错}
}

试图在静态初始化块中初始化final变量【编译报错

public class FinalTest {private final String name;// 编译报错static{name = "BreezAm"; //编译报错,就算name定义时已经被初始化此处编译期也会报错}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm}
}
  1. 静态final成员变量可以在静态初始化块中初始化,但不可以在初始化块中初始化。
  • 静态初始化块中初始化成员变量【编译通过
public class FinalTest {private static final String name;//  定义一个静态、不可变的变量static {name = "BreezAm";//在静态初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm}
}
  • 试图在静态初始化块中初始化成员变量【编译报错
public class FinalTest {private static final String name;//  编译报错{name = "BreezAm";//在初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm}
}
  1. 在类的构造器中初始化,但静态final成员变量不可以在构造函数中初始化。
  • 构造器中初始化非静态final成员变量【编译通过
public class FinalTest {private final String name;//   定义一个成员变量【未初始化】public FinalTest() {name = "BreezAm";//在构造器中初始化final类型的成员变量}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm}
}

final方法

当一个方法被声明为final时,该方法不允许任何子类重写这个方法,但子类仍然可以使用这个方法。[注意final方法可以被重载]


另外,还有一种被称为inline(内联)的机制,当调用一个被声明为final的方法时,直接将方法主体插入到调用处,而不是进行方法调用(类似于C++中的inline),这样做可以提高程序的效率

案例:

/*** 父类*/
public class Father {/*** 编写一个final方法*/public final void doAction(){System.out.println("我是final方法、我不可以被重写,但是你可以用噢!渣女!!");}
}

子类试图重写final方法【编译报错

/*** 子类*/
public class Children extends Father {public final void doAction(){ //编译报错、因为父类doAction方法是final类型的,所以不可以被重写}public static void main(String[] args) {}
}

使用父类中的final方法【编译通过

/*** 子类*/
public class Children extends Father {public static void main(String[] args) {Children children = new Children();children.doAction();}
}

输出:

我是final方法、我不可以被重写,但是你可以用噢!渣女!!

子类重载父类中的final方法

/*** 子类*/
public class Children extends Father {/*** 重写父类中被声明为final的方法* @param a* @param b*/public final void doAction(int a,int b){ // 可以被重载,哈哈,被我发现了System.out.println("a:"+a);System.out.println("b:"+b);}public static void main(String[] args) {Children children = new Children();children.doAction(20,30);}
}

输出:

a:20
b:30

final参数

用来表示这个参数在这个函数内部不允许被修改

案例:

public class FinalTest {/*** 编写一个带参数为final的方法** @param name*//*public void doActionFinal(final String name) {name = "我想修改name,但是编译报错了,难过!!"; //编译不通过}*//*** 编写一个带非final参数的方法** @param name*/public void doAction(String name) {System.out.println("修改前:" + name);name = "name参数不是final的,我修改成功了,一个字:巴适!"; //编译通过System.out.println("修改后:  " + name);}public static void main(String[] args) {FinalTest test = new FinalTest();//test.doActionFinal("BreezAm");test.doAction("BreezAm");}
}

输出:

修改前:BreezAm
修改后:  name参数不是final的,我修改成功了,一个字:巴适!

final类

当一个类被声明为final时,此类不能被继承,所有的方法都不能被重写。但这并不表示final类的成员变量也是不可变的,要想做到final类的成员变量不可改变,必须给成员变量增加final修饰。注意:一个类不能即被声明为abstract,又被声明为final【抽象类不能声明为final】。

试图继承被声明为final的类【编译失败

/*** 父类*/
public final class Father {
}
/*** 子类*/
public class Children extends Father {  //编译报错}

试图将一个abstract类声明为final【编译失败

/*** 父类*/
public final abstract class Father { //编译失败,抽象类不能声明为final}

修改final类的成员变量

/*** 父类*/
public final class Father {private String name = "BreezAm";private final int num = 2018010110;public void doAction() {name = "清风";//修改final类的非final成员变量 编译通过num = 2019010110;//修改final类的final成员变量 编译失败}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

出道50年+!乘风破浪的编程语言们,能二次翻红吗?

来源 | 编程技术宇宙责编| Carol继上次哈希表华山论剑之后,比特宇宙编程语言联合委员会又来搞事情了。委员会要做一套全新的系统,涉及后端、前端、客户端三大块,为选择什么样的语言组合拿不定主意。为了体现公平,委员会特举办一次…

Spotify如何使用Cassandra实现个性化推荐

在Spotify我们有超过6000万的活跃用户,他们可以访问超过3000万首歌曲的庞大曲库。用户可以关注成千上万的艺术家和上百个好友,并创建自己的音乐图表。在我们的广告平台上,用户还可以通过体验各种音乐宣传活动(专辑发行&#xff0c…

RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 多机版本)

接上一篇:RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包nginx 单机版本) 前端和后端不在一个服务器上,如何部署呢? 文章目录1. 服务器和软件部署2. 后端部署3. 前端部署4. 登录5. 效果图1. 服务器和软件部署 服…

三个不同线程顺序打印ABC十种写法【并发编程JUC】

夫陶公清风千古,余又何人,敢称庶几 个人博客地址:http://www.breez.work 📖写法一:使用信号量Semaphore public class Foo {private Semaphore semaphoreB new Semaphore(0);private Semaphore semaphoreC new Sem…

技术直播:数据科学到底该怎么“玩”?

90年代初,王健林抓住的房地产的机遇,现在才敢说“一个亿的小目标”;千禧年后 ,“马爸爸”抓住了电商的机遇,现在才能说“我对钱没有兴趣”。今年由于特殊情况,加速了远程办公、在线教育和在线医疗的发展&am…

Apache Flink 为什么能够成为新一代大数据计算引擎?

众所周知,Apache Flink(以下简称 Flink)最早诞生于欧洲,2014 年由其创始团队捐赠给 Apache 基金会。如同其他诞生之初的项目,它新鲜,它开源,它适应了快速转的世界中更重视的速度与灵活性。 大数…

超燃!支付宝技术双11纪录片《一心一役》全球独家首发

​和过去10年一样,2019年天猫双11又创造了一个全新的纪录。 这个数字背后,是数代支付宝工程师们殚精竭虑、不断突破技术难关。 今年双11之前,小编邀请到11位经历双11的技术同学口述实录,特别筹备了纪录片《一心一役》&#xff0c…

RabbitMQ消息队列简单异步邮件发送和订单异步处理实战【应用解耦】【异步削峰】

介绍 📖源码地址: https://gitee.com/breez/mq-shop 介绍 使用RabbitMQ消息队列异步发送短信和邮件、订单异步处理【流量削峰】 软件架构 技术栈 序号名称1SpringBoot2SpringMVC3Mybatis plus4RabbitMQ5SpringBoot Mail 特点: 邮件发送的封装三大发…

秋名山老司机从上车到翻车的悲痛经历,带你深刻了解什么是 Spark on Hive!| 原力计划...

作者 | Alice菌责编 | 夕颜出品 | CSDN博客本篇博客将为大家分享的内容是如何实现Spark on Hive,即让Hive只作为存储角色,Spark负责sql解析优化,执行…话不多说,直接上车!上车前需知Spark on hive 与 hive on spark 的…

从电商到软件市场,阿里双11战火蔓延

2019年“双十一”,是阿里天猫奋战的第11个年头,更是阿里在电商行业的一个重要的里程碑。今年,整个阿里系也在“一心一役”全面出击,作为阿里旗下的重要大将——阿里云也加入了这场购物狂欢,将火热的购物氛围从C端消费者…

RuoYi-Cloud 部署篇_01(linux环境 mysql+nginx版本)

文章目录一、基础准备1. 技术选型2. 源码克隆3. 安装依赖4. 将 RuoYi-Cloud 项目导入到 IDEA5. 安装启动Mysql6. 安装启动Redis7. 创建数据库,执行 SQL脚本文件二、安装与配置 nacos2.1. 下载nacos2.2. 安装 nacos2.3. nacos持久化配置2.4. 执行脚本文件2.5. nacos连…

SpringBoot集成Elasticsearch实现博客高亮搜索

文章目录效果展示二、使用步骤1.引入maven依赖2. 编写spplication.properties3.配置客户端4.高亮搜索5.转换成实体对象总结效果展示 虽然看起来巴适,但是挺简单的! 📝 英文检索 📝 中文单字检索 二、使用步骤 1.引入maven依赖…

淘系技术,实力为2019年双11而战!稳!

2019 天猫双 11 全球狂欢节96秒成交额破百亿,24小时总成交额2684亿,创造了交易创建峰值 54.4万笔/秒的历史记录。天猫双11,已经不仅是购物节,也是品牌成长节、消费者互动节。天猫双11更是是商业的奥林匹克。 今年&…

上班从不迟到,生病不敢请假,加班唯命是从,明明已经很拼命了,为什么还是缺钱?...

为了省几百块钱房租,每天在路上多花两三个小时;为了少花几毛钱,买包纸巾也要货比三家;被上司大声指责,为了保住饭碗,只能陪着笑脸......上班从不迟到,生病不敢请假,加班唯命是从&…

RuoYi-Cloud 部署篇_02(linux环境 mysql+nginx版本)

文章目录一、模块配置修改1. ruoyi-gateway-dev.yml2. ruoyi-auth-dev.yml3. ruoyi-system-dev.yml4. ruoyi-gen-dev.yml5. ruoyi-job-dev.yml6. ruoyi-file-dev.yml二、后端配置预启动2.1. 部署资料整合2.2. 模块端口划分2.3. 组件端口划分2.4. 服务脚本编写2.5. 前端编译生产…

Flink State 有可能代替数据库吗?

有状态的计算作为容错以及数据一致性的保证,是当今实时计算必不可少的特性之一,流行的实时计算引擎包括 Google Dataflow、Flink、Spark (Structure) Streaming、Kafka Streams 都分别提供对内置 State 的支持。State 的引入使得实时应用可以不依赖外部数…

简易投票系统数据库设计

介绍 简易版的投票系统数据库设计. 发现设计有误请在评论区指出,谢谢! 一、截图 项目表 选项表 投票表 二、代码 票表 CREATE TABLE as_ticket (id varchar(64) NOT NULL COMMENT 主键,title varchar(100) DEFAULT NULL COMMENT 投票标题,descr…

万级规模 K8s 如何管理?蚂蚁双11核心技术公开

阿里妹导读:Kubernetes 大幅降低了容器化应用部署的门槛,并以其超前的设计理念和优秀的技术架构,在容器编排领域拔得头筹。越来越多的公司开始在生产环境部署实践。本文将分享蚂蚁金服是如何有效可靠地管理大规模 Kubernetes 集群的&#xff…

定了!2020年,6种将死的编程语言!

编程界语言排行榜又要面临一次全新的洗牌,六大编程语言将要黄了!此消息一出,令众多程序员心碎!那么这将“亡”的六大语言中有你所擅长的吗?Perl,Haskell,Ruby,Visual Basic.NET&…

RuoYi-Cloud 部署篇_03(linux环境 Mysql+nginx版本)

文章目录一、localhost无法路由1. nacos控制台2. sentinel控制台3. admin控制台二、思路分析2.1. 现象分析2.2. 原因分析2.3. 解决思路三、解决方案(第一种)3.1. 调整路由url3.2. 效果验证四、解决方案解决方案(第二种)4.1. 域名分…