聊聊Java的final关键字
Java的final关键字在日常工作中经常会用到,比如定义常量的时候。如果是C++程序员出身的话,可能会类比C++语言中的define或者const关键字,但其实它们在语义上差距还是挺大的。
在Java中,final可以用来修饰类、方法和变量(包括成员变量和局部变量)。我们先来简单介绍一下final关键字的这几个用法。
一、final修饰类
常见的一个例子就是String类。当用final修饰一个类时,表明这个类不能被继承,并且final类中的所有成员方法都会被隐式地指定为final方法,但成员变量不会变。
一般来说,我们还是尽量不要将类设计为final类,除非我们出于某些因素的考虑必须这么做。比如不希望类被继承,也就是说不希望类被修改语义。如果我们继承String类,那么就可以定义一个可被修改的String类,这对于String类的使用者来说近乎是一种灾难。
二、final修饰方法
使用final修饰方法有两个原因:
是把方法锁定,以防任何继承类修改它的含义;
是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
同final类相似,只有在想明确禁止该方法在子类中被覆盖的情况下才将方法设置为final。另外,类的private方法会隐式地被指定为final方法,其语义要求private方法不能被重新定义。
三、final修饰变量
final用得最多的地方就是修饰变量。对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,但是它指向的对象的内容是可变的。
由于final变量初始化之后无法修改,针对这个特性,Java编译器对此进行了优化。当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。这个优化通常对于程序逻辑没有太多影响,但如果用==比较的时候,可能会出乎意料。具体可以参考之前的文章《Java自动装箱和拆箱》。
综上所述,final在修饰类和方法时,代表不能再修改其定义,而在修饰变量时,则类似C++中的const关键字,用于表示常量。
一个好的编程习惯是我们应该尽量将变量声明为final的,除非变量必须是可变的。例如当你在方法中不需要改变作为参数的变量时,可以使用final进行声明,这样可以防止你无意的修改,尤其是当你的方法很长很复杂的时候。当然是否用final修饰参数,都不会影响方法之外的变量。
使用final关键字还有个好处,是它能确保初始化过程的安全性,可以不受限制的访问不可变对象,并在多线程共享这些对象时无须同步。当我们有多个基本类型的变量,他们之前需要保持数据一致的时候,通常的办法是使用synchronized关键字来保证对这些变量操作的原子性。如果使用final关键字,我们可以定义新类,包含这些变量(用final修饰),这样这些变量就成了常量,变量修改操作就成了赋值操作(是原子操作),这样就避免了使用加锁同步。当然不可修改的变量也会导致很多小对象的生成,加重垃圾回收的负担,相较而言可以忽略了。
最后,我们知道,在匿名内部类的方法参数只能访问final类型的局部变量,编译器也强制要求这一点,这是为什么呢?其根本原因在于局部变量的生命周期与匿名内部类对象的生命周期不一致。局部变量所在的方法执行完之后,匿名内部类对象仍然存在,这时匿名内部类对象就无法访问到该局部变量,因为该局部变量的生命周期已经结束。使用final修饰局部变量,其实是将局部变量“复制”了一份,复制品直接作为局部内部中的数据成员,这样就解决的生命周期不一致的问题。
聊聊Java的final关键字的更多相关文章
- JAVA面向对象-----final关键字
JAVA面向对象-–final关键字 1:定义静态方法求圆的面积 2:定义静态方法求圆的周长 3:发现方法中有重复的代码,就是PI,圆周率. 1:如果需要提高计算精度,就需要修改每个方法中圆周率. 4 ...
- java之final关键字
final关键字(可以读不可以写.只读) 1.final的变量的值不能够被改变 ①.final的成员变量 ②.final的局部变量(形参) //意思是“实参”一旦传进我的方法里面,就不允许改变 2.f ...
- Java的final关键字详解
Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...
- java中final 关键字的作用
final 关键字的作用 java中的final关键字可以用来声明成员变量.本地变量.类.方法,并且经常和static一起使用声明常量. final关键字的含义: final在Java中是一个保留的关 ...
- Java基础 -- final关键字
在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们来了解一下final ...
- Java中final关键字修饰变量、方法、类的含义是什么
Java中的关键字final修饰变量.方法.类分别表示什么含义? 先看一个简单的介绍 修饰对象 解释说明 备注 类 无子类,不可以被继承,更不可能被重写. final类中的方法默认是final的 方法 ...
- java浅析final关键字
谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. ...
- 关于Java中final关键字的详细介绍
Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...
- java基础---->final关键字的使用
这里介绍一些java基础关于final的使用,文字说明部分摘自java语言规范.心甘情愿这四个字,透着一股卑微,但也有藏不住的勇敢. Final关键字的说明 一.关于final变量规范说明 .A fi ...
随机推荐
- Java Junit测试框架
Java Junit测试框架 1.相关概念 Ø JUnit:是一个开发源代码的Java测试框架,用于编写和运行可重复的测试.它是用于单元测试框架体系xUnit的一个实例(用于java语言).主要 ...
- C++模式学习------策略模式
当遇到同一个对象有不同的行为,方法,为管理这些方法可使用策略模式. 策略模式就是对算法进行包装,是把使用算法的责任和算法本身分割开来.通常把一个系列的算法包装到一系列的策略类里面,这些类继承一个抽象的 ...
- MySQL 双主问题集
最近试用MySQL高可用方案,需要配MySQL双主,对期间遇到的问题做下记录. 1.导出锁表问题 mysqldump 命令增加参数 --skip-opt -q 可避免导出时锁表: 2.导出\导入所有数 ...
- Linux内核分析第八周——进程的切换和系统的一般执行过程
Linux内核分析第八周--进程的切换和系统的一般执行过程 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...
- debian修改时区
这里提供两种方法 一.使用dpkg-reconfigure修改 # dpkg-reconfigure tzdata Current default time zone: 'Asia/Shanghai' ...
- Java之Java程序与虚拟机
Java为什么要在虚拟机中运行 简单的来说,Java作为一门高级程序语言,语法复杂,抽象度高,不能直接翻译为机器码在机器上运行,所以设计者就设计了虚拟机,通过编译器将Java程序转换成虚拟机所能识别的 ...
- java插件之Lombok
使用注释来减少Java中的重复代码 @NonNull - 或者:我怎么学会停止担心和喜欢上了NullPointerException. @Cleanup - 自动资源管理:安全地调用您的close() ...
- 解题:APIO 2014 序列分割
题面 拆开式子我们发现切割顺序不影响答案,所以可以设计出一个$dp[i][j]$表示到$i$为止切了$j$刀的最大收益之类的,然后做个前缀和就可以转移了. $dp[i][j]=min(dp[i][j] ...
- 解题:POI 2007 Tourist Attractions
题面 事实上这份代码在洛谷过不去,因为好像要用到一些压缩空间的技巧,我并不想(hui)写(捂脸) 先预处理$1$到$k+1$这些点之间相互的最短路和它们到终点的最短路,并记录下每个点能够转移到时的状态 ...
- 解题:SHOI 2012 回家的路
题面 完了,做的时候已经想不起来分层图这个东西了QAQ 对于这种“多种”路径加中转站的题,还有那种有若干次“特殊能力”的题,都可以考虑用分层图来做 显然只需要记录所有的中转站+起点终点,然后拆出横竖两 ...