tnblog
首页
视频
资源
登录

你真的了解final吗?

5679人阅读 2018/12/17 16:20 总访问:169683 评论:0 收藏:0 手机
分类: JAVA

final关键字可以修饰类,方法,变量

1、用final修饰变量

(1)final成员变量表示常量,只能被赋值一次,赋值后值不再改变。

    

 final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。


 当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。


(2)当对对象的引用使用final时,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法把它改为指向另一个对象。然而对象其自身却是可以被修改的。

  1. class Value {
  2. int i;
  3. public Value(int i) this.i = i; }
  4. }
  5. public FinalData {
  6.     private Value v1 = new Value(11);
  7.     private final Value v2 = new Value(22);
  8.     private final int[] a = {12345};
  9. public static void main(String[] args) {
  10. FinalData fd1 = new FinalData();
  11.         fd1.v2.i++; // v2是对象,不是常量,v2用final修饰,无法把它改为指向另一对象,但对象自身是可以被修改的
  12.         fd1.v1 = new Value(9);  // v1不是final,可以将它指向另一个对象
  13.     //   fd1.v2 = new Value(0);  // v2是final,不可以将它指向另一个对象
  14.         for (int i = 0; i < fd1.a.length; i++){
  15.           fd1.a[i]++; // 数组是对象,对象不是常量,其自身可以改变
  16.         }
  17.     //   fd1.a = new int[3];   //错误,数组a是final修饰的引用,无法将它指向另一个对象
  18. }

(3)一个既是static又是final的域只占据一段不能改变的存储空间。

(4)Java允许生成“空白final”,所谓空白final是指被声明为final但又未给定初值的域。无论什么情况,编译器都确保空白final在使用前必须被初始化。总之,final是一定要初始化的,如果不在声明处初始化,那就在构造器中初始化。记住一定要初始化,否则编译不通过。

  1. class Poppet {
  2.     private int i;
  3.     Poppet(int i) { this.i = i; }
  4. }
  5. public class BlankFinal {
  6.     private final int i = 0;
  7.     private final int j;    // 空白final
  8.     private final Poppet p; // 空白final引用
  9.     public BlankFinal(){
  10.         j = 1;  // 初始化空白final
  11.         p = new Poppet(1);  // 初始化空白final引用
  12.     }
  13.     public BlankFinal(int x){
  14.         j = x;  // 初始化空白final
  15.         p = new Poppet(x);  // 初始化空白final引用
  16.     }
  17.     public static void main(String[] args){
  18.         new BlankFinal();
  19.         new BlankFinal(47);
  20.     }
  21. }

(5)用final修饰参数,Java允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所指向的对象。

  1. class Gizmo {
  2.     public void spin(){}
  3. }
  4. public class FinalArguments {
  5.     void with(final Gizmo g){
  6.         //! g = new Gizmo();    // 错误,g是用final修饰的,无法将它指向另一个对象
  7.     }
  8.     void without(Gizmo g){
  9.         g = new Gizmo();    // g不是final类型,可以将它指向新的对象
  10.         g.spin();
  11.     }
  12.     // void f(final int i){ i++; }  // 错误,i是用final修饰的,无法改变它的值。
  13.     int g(final int i)return i + 1; } // 正确,i的值没有被改变
  14.     public static void main(String[] args){
  15.         FinalArguments bf = new FinalArguments();
  16.         bf.with(null);
  17.         bf.without(null);
  18.     }
  19. }

2、用final修饰方法

用final修饰的方法不能被重写

使用final方法的原因有两个:

(1)把方法锁定,以防任何继承类修改它的含义。这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。

(2)效率,在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。


final和private:类中所有的private方法都隐式地指定为final的。由于无法取用private方法,所以也就无法覆盖它。可以对private方法添加final修饰词,但这并不能给该方法增加任何额外的意义。


3、用final修饰类


用final修饰的类无法被继承,即它不能有子类。请注意:final的域可以根据个人的意愿选择为是或不是final。不论类是否被定义为final,相同的规则都适用于定义为final的域。然而,由于final类禁止继承,所以final类中所有的方法都会隐式指定为final的,因为无法覆盖它们。在final类中可以给方法添加final修饰词,但这不会增添任何意义。

在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。


深入理解final的好处


(1)final关键字提高了性能。JVM和Java应用都会缓存final变量。


(2)final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。


(3)使用final关键字,JVM会对方法、变量及类进行优化。


(4)创建不可变类要使用final关键字。不可变类是指它的对象一旦被创建了就不能被更改了。String是不可变类的代表。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。


评价

抖音带货达人怎么样赚钱

文/全民带货达人抖音短视频带货的人是越来越多了,各大电商平台也相继进入了短视频平台。而目前除了自己在短视频平台开店的...

ReportingServicesService.exe是什么,占用内存太高可以关闭

ReportingServicesService.exe是SQLServer的报表服务。如果你不使用报表的话可以将其停掉,不会影响数据库的其他工作。 而...

mysql 表名区分大小写

MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:数据库名与表名是严格区分大小写的;表的别名是严格区分大...

该用 Java 12 还是坚持 Java 11

搭上火箭也追不上的 Java 更新速度,不少程序员们大呼,我可不可以坚持使用 Java 8?!但是对于已使用到 LTS 版本的 Java 1...

通俗易懂,什么是.NET?什么是.NET Framework什么是.NET Core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

怎样解决安卓在微信浏览器对于第三方网页的两次请求问题

之前的项目是没有这种情况的,但是最近发现安卓手机在微信浏览器访问第三方网页时,页面点击某个按钮,写日志显示只触发了...

c中var叫什么名字呢匿名类型?

c#中var叫什么名字呢?匿名类型? 看看官方称呼,也就是vs中的提示吧没错!就是隐式类型!

如何解决导航栏过长而滑不动问题

这是导航栏文章本来可以滑动的,但编写了加载时间后就划不动了,然后滑动文章呈现出这种效果:这该如何解决?

LinQ是什么

一切皆可LINQ,一切皆有可能?LINQ(发音:Link)是语言级集成查询(LanguageINtegratedQuery)?LINQ是一种用来进行数据访...

c中.的作用

c#中?.的作用可以减少为空判断,其实就是语法糖。例如:.Where(a =&gt; a.Type == (int)TNMessageDAL.MessageType.comment...

Soap、Http、TCP/IP 三个基本的通讯协议有什么区别

TCPTCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯...

什么是CC-BY-NC-SA协议有什么规定

前言:他来了 他来 他骑着Tomcat 走来了 没错就是我 你们幽默风趣的小付早上给各位大爷们分享了堆和栈 虽然是是转载的但是确...

有什么建议给即将出国留学的学生

1.学好英语有人肯定会纳闷了,为什么马上就要出国了,你还建议我学好英语呀。那是因为你雅思是考到6.5、7,但是当你初到国...

互联网发展到什么阶段了解企业该如何应用互联网的力量。

身边的很多人都说2019年是中国企业近十年最坏的一年,也是未来十年最好的一年,我倒是认为这样的预测稍显悲观。历史已经无...

东途网:新手如何运营抖音最全运营技巧、注意事项来啦!

东途网:www.dtwl.top新手如何运营抖音?最全运营技巧、注意事项来啦!抖音是目前最火爆的短视频,越来越多的人都离不开短视...
sometimes ever,sometimes never
排名
21
文章
27
粉丝
11
评论
12
MySQL数据库基础
剑轩 : 大神教我学mysql!
MySQL概述与安装配置
剑轩 : PHP是目前最流行的 Web 开发语言
JAVA8 十大新特性详解
叼着奶瓶逛酒吧 : 文章写得真心不错,加油哈
Java学习 - Java语言基础
剑轩 : 每个小标题颜色加深一点会更好哦
Java学习 - Java语言简介
剑轩 : 请注意,java大神开讲了
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
安逸可以抵挡恐惧,但安逸难以久存。