聊聊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 ...
随机推荐
- Logrotate还有谁记得它??
我发现很多人的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮子,这真是让人沮丧啊!就好比明明身边躺着现成的性感美女,大家却忙着自娱 ...
- HDU3046_Pleasant sheep and big big wolf
给一个n*m的数字阵,1表示羊的位置,2表示狼的位置,0表示没有东西,可以通过.在每个格子的4边都可以建立围栏,有围栏的话狼是不能通过的. 现在求最少建立多少围栏能够保证狼无法接触到羊. 题目的模型很 ...
- 清华集训2015-Day 2
校内测试做到了,于是就把解题报告发出来. 简单回路 一个 \(n\times m\) 的方格纸,有 \(k\) 个障碍点.\(q\) 次询问,每次询问 \((x,y)\) ,问有多少条简单回路经过 \ ...
- BZOJ5312 冒险(线段树)
记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...
- 015 反射中的 Class.forName() 与 ClassLoader.loadClass() 的区别
作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...
- Longest Word in Dictionary through Deleting - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Longest Word in Dictionary through Deleting - LeetCode 注意点 长度一样的字符串要按字典序返回较小的 ...
- Hplsql报错:...HiveSQLExpection:Error while compiling statement:No privilege 'Select' found for inputs {.....}
实践hplsql时,遇到的问题总结一下,若有不对的地方,欢迎交流. 一.Hplsql简介 hplsql的介绍详见:http://lxw1234.com/archives/2015/09/492.htm ...
- linux内核分析 第五周读书笔记
第18章 调试 内核调试的难度大于用户级 一.准备开始 开始之前需要的是: 一个行为可靠且定义明确的bug 一个隐匿bug的内核版本 相关内核代码的知识和运气 想要成功的调试,取决于能不能将这些bug ...
- 构建工具-----Gradle-----安装配置
介绍 Gradle 是一款构建工具,继 Ant .Maven 之后的现代构建工具. 下载 Gradle 下面是 Gradle 的官方网站地址: Gradle l Modern Open-Source ...
- 解题:JXOI 2018 游戏
题面 From ZRQ,很好的计数题 我们可以发现这$len=r-l+1$个数中有一些是必须被查到的,即它们不是一些数的倍数,它们的数目$imp$可以通过一次埃氏筛求出. 在一个排列中可怜查到某个位置 ...