前言

一直想写写这个话题。代表公司也面试过一些求职者,每次面试我必问的两个问题之一 就是“请你谈一谈对于final关键字的理解”。这是一个简单的小问题,但是不要小看它,通过对这个问题的回答以及一些简单的扩展就能看出一个求职者的基 础是否扎实以及是否有钻研精神。OK,开始进入主题。

final关键字的作用

相信对于final的用法,大多数人都可以随口说出三句话:

1、被final修饰的类不可以被继承

2、被final修饰的方法不可以被重写

3、被final修饰的变量不可以被改变

重点就是第三句。被final修饰的变量不可以被改变,什么不可以被改变呢,是变量的引用?还是变量里面的内容?还是两者都不可以被改变?写个例子看一下就知道了:

 1 public class FinalString
2 {
3 private String str;
4
5 public FinalString(String str)
6 {
7 this.str = str;
8 }
9
10 public String getStr()
11 {
12 return str;
13 }
14
15 public void setStr(String str)
16 {
17 this.str = str;
18 }
19 }
1 public class Test
2 {
3 public static void main(String[] args)
4 {
5 final FinalString fs = new FinalString("1");
6 fs.setStr("2");
7 System.out.println(fs.getStr());
8 }
9 }

运行一下,一点问题都没有。稍微修改一下呢:

1 public static void main(String[] args)
2 {
3 final FinalString fs = new FinalString("1");
4 final FinalString fss = new FinalString("333");
5 fs = fss;
6 }

第7行报错了,“The final local variable fs cannot be assigned”。可见,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的。OK,那final修饰数组呢?

1 public static void main(String[] args)
2 {
3 final String[] strs0 = {"123","234"};
4 final String[] strs1 = {"345","456"};
5 strs1 = strs0;
6 strs1[1] = "333";
7 }

同样,第5行报错了“The final local variable strs1 cannot be assigned”,第6行一点问题都没有。变量和数组一样,都是引用不可变,引用指向的内容可变。实际上如果用过FindBugs插件的应该知道,假如代码里面用final修饰了一个数组,那么改行代码会被作为findBugs的一个bug被查找出来,因为“用final修饰数组是没有意义的”。

接下来,再看一下用final修饰方法参数的场景:

 1 public class Test
2 {
3 public static void main(String[] args)
4 {
5 FinalString fs = new FinalString("");
6 A(fs);
7 }
8
9 private static void A(final FinalString fs)
10 {
11 fs.setStr("123");
12 FinalString fss = new FinalString("22");
13 fs = fss;
14 }
15 }

一样,同样是13行报错,11行没有问题,相信大家已经知道原因了。

总结

“引用”是Java中非常重要的一个概念,对于引用的理解不深,很容易犯一些自己都没有意识到的错误。被final修饰的变量,不管变量是在是哪种变量,切记不可变的是变量的引用而非引用指向对象的内容。另外,本文中关于final的作用还有两点没有讲到:

1、被final修饰的方法,JVM会尝试为之寻求内联,这对于提升Java的效率是非常重要的。因此,假如能确定方法不会被继承,那么尽量将方法定义为final的,具体参见运行期优化技术的方法内联部分

2、被final修饰的常量,在编译阶段会存入调用类的常量池中,具体参见类加载机制最后部分和Java内存区域

final的作用的更多相关文章

  1. 谈谈final的作用

    前言 一直想写写这个话题.代表公司也面试过一些求职者,每次面试我必问的两个问题之一就是“请你谈一谈对于final关键字的理解”.这是一个简单的小问题,但是不要小看它,通过对这个问题的回答以及一些简单的 ...

  2. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  3. Java中final的作用

    Java中Final可以被用于变量,方法,类.具体来说: 1, Final 变量 修饰主类型时,制定变量为常数,不希望被改变 修饰类类型时,表示变量的句柄不变,不能被指定指向新的变量 修饰参数时,参数 ...

  4. 回顾static与final的作用

    static是java中非常重要的一个关键字,而且它的用法也很丰富,主要有四种用法: 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享: 用来修饰成员方法,将其变为类方法,可以直接 ...

  5. final 的作用

    1.修饰类 类不能被继承 2.修饰方法 目的有二: 1)禁止子类重写该方法 2)执行效率(JVM相关的东西,不用太关注) 3.修饰变量 final修饰原始类型的变量,该变量不能被修改 final修饰引 ...

  6. 浅析Java中的final关键字(转载)

    自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...

  7. 浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  8. java基础复习:final,static,以及String类

    2.final 1)为啥String是final修饰的呢? 自己答: 答案: 主要是为了“效率” 和 “安全性” 的缘故.若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所 ...

  9. 浅析final 关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...

随机推荐

  1. java—不同的用户登录以后可以看到不同的菜单(后台可以实现对用户菜单的管理) 1 (55)

    实现不同的用户登录以后可以看到不同的菜单.(后台可以实现对用户菜单的管理.) 第一步:分析数据结构        1:用户表 表名:users 列名 类型 说明 id Varchar(32) 主键 n ...

  2. 【OCP-12c】CUUG 071题库考试原题及答案解析(23)

    23.choose the best answer View the Exhibits and examine PRODUCTS and SALES tables. You issue the fol ...

  3. 真机测试 Thnetwork connection was lost. No profiles for 'xxx' were found: Xcode couldn't find a provisioning profile matching 'xxx'. Code signing is required for product type

    最近接手了一个新项目,是从外包接手的,结果出现了很多问题,真的很崩溃,崩溃,吐槽一下 问题一:一直请求不到数据,因为外包只做了一版,上架的这个版本是可以显示数据的,但是给我的项目是没有数据的,因为并没 ...

  4. soapui加载天气预报接口报错Characters larger than 4 bytes are not supported: byte 0xb1 implies a length of more than 4 byte的解决办法

    soapui加载天气预报接口时报错如下: Error loading [http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl ...

  5. git简易入门(github)

    本文讲解下git的使用,包括使用git上传项目工程到github,以及错误解决. 1.安装git 使用apt-get安 sudo apt-get update sudo apt-get install ...

  6. vue+ivew-admin开发项目,内存占用过大解决办法

    项目用的ivew+admin ivewUI,直接从github上拉下来用的,配置也没改,我们页面比较多,大该30个页面的样子,一启用,我们的电脑就卡了,然后,看一下,内存占用 1.5G+了,我们电脑4 ...

  7. mongodb主从备份 和 手动主从切换

    环境: 主机A:172.16.160.91 主机B:172.16.160.92 配置主机A [root@master zhxf]# cat docker-compose.yml version: '3 ...

  8. JavaScript DOM编程艺术 笔记(四)

    DOM document   object model(map) 家谱树---节点树 父 子  兄弟 元素节点  <div> 文本节点  内容 属性节点   value  src getE ...

  9. PHP中filesystem的使用

    PHP中filesystem的使用 最近在用腾讯云COS上传对象的时候,涉及到文件流的使用 参考文档:https://cloud.tencent.com/document/product/436/12 ...

  10. 洛谷 P2473 [SCOI2008]奖励关(状压dp+期望)

    题面 luogu 题解 \(n \leq 15\) 状压 \(f[i][S]\)表示第\(i\)轮,吃过的集合为\(S\) 正着转移好像有点复杂 考虑逆推转移(正着转移应该也行) \(f[i][S]\ ...