final 在 Java 中是一个保留的关键字,可以声明变量方法

什么是final变量 / 类 / 方法?

任何变量前被 final 修饰就是 final 变量,定义的类前被 final 修饰就是 final 类,任何方法前被 final 修饰就是final方法。

一、final类

当用 final 修饰一个类时,表明这个类不能被继承。图中箭头指向的地方,那句英文翻译过来就是不能继承 Cat 类。

如果把 final 关键字去掉,就可以了。这样就不会报错了!

使用final类要注意,一旦被设置为final类就无法被继承

 二、final方法

下面这段话摘自《Java编程思想》第四版第143页

“使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的 Java 版本中,不需要使用 final 方法进行这些优化了。“

意思是如果方法足够完整,子类不需要修改就可以使用final方法,避免子类被修改。final方法是静态绑定的,在编译时就确定好是哪个类的方法,所以final方法要比非final方法快一些

三、final变量

变量被 final 修饰就是就是 final 变量,那么问题来了,final 变量和普通变量到底有啥区别?

举个栗子:

public class Main {
   public static void main(String[] args) {
       String a = "xiaomeng2";
       final String b = "xiaomeng";
       String d = "xiaomeng";
       String c = b + 2;
       String e = d + 2;
       System.out.println((a == c));
       System.out.println((a == e));
   }
}

true

false

  • 变量a指的是字符串常量池中的 xiaomeng2;

  • 变量 b 是 final 修饰的,变量  b 的值在编译时候就已经确定了它的值,换句话说就是提前知道了变量 b 的内容到底是个啥,相当于一个编译期常量;

  • 变量 c 是 b + 2得到的,由于 b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(xiaomeng)来进行计算,所以 c 生成的也是一个常量,a 是常量,c 也是常量,都是 xiaomeng2 而 Java 中常量池中只生成唯一的一个 xiaomeng2 字符串,所以 a 和 c 是相等的!

  • d 是指向常量池中 xiaomeng,但由于 d 不是 final 修饰,也就是说在使用 d 的时候不会提前知道 d 的值是什么,所以在计算 e 的时候就不一样了,e的话由于使用的是 d 的引用计算,变量d的访问却需要在运行时通过链接来进行,所以这种计算会在堆上生成 xiaomeng2 ,所以最终 e 指向的是堆上的 xiaomeng2 , 所以 a 和 e 不相等。

也就是说a和c是常量池的xiaomeng2,e是堆上的xiaomeng2 

final修饰变量和修饰引用变量有什么不同

final修饰的常量变量不可改变,修饰的引用变量引用不可改变,引用的对象可改变

举个栗子:

修改普通变量int报错

修饰的引用变量引用不可改变是什么意思

再举个栗子:

test是引用变量,被final修饰,如果再把test这个引用指向别的地方就会报错

引用的对象可改变又是什么意思

举个栗子:

这段代码执行结果是2,没有报错,说明test这个对象里面i的值增加了1,引用对象的内容变了

final关键字好处总结:

  • final方法比非final快一些

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

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

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

Final关键字解析的更多相关文章

  1. Java中的final关键字解析

    一.final关键字的基本用法 1.修饰类   当用final修饰一个类时,表明这个类不能被继承.注意: final类中的成员变量可以根据需要设为final, final类中的所有成员方法都会被隐式地 ...

  2. Java并发指南5:JMM中的final关键字解析

    本文转载自互联网,侵删   与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问.对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的 ...

  3. 从缓存入门到并发编程三要素详解 Java中 volatile 、final 等关键字解析案例

    引入高速缓存概念 在计算机在执行程序时,以指令为单位来执行,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入. 由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这 ...

  4. 【Java面试题】2 Java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?超详细解析

    /* * 问题:使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的 ...

  5. 解析Java中final关键字的各种用法

    首先,我们可以从字面上理解一下final这个英文单词的中文含义:“最后的,最终的; 决定性的; 不可更改的:”.显然,final关键词如果用中文来解释,“不可更改的”更为合适.当你在编写程序,可能会遇 ...

  6. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  7. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  8. volatile关键字解析(转)

    volatile关键字解析 转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在J ...

  9. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析   Java并发编程:volatile关键字解析 ...

随机推荐

  1. Webdriver测试脚本2(控制浏览器)

    Webdriver提供了操作浏览器的一些方法,例如控制浏览器的大小.操作浏览器前进和后退等. 控制浏览器窗口大小 有时候我们希望能以某种浏览器尺寸打开,让访问的页面在这种尺寸下运行.例如可以将浏览器设 ...

  2. [K/3Cloud] 使用操作还是服务

    现在菜单点击事件既可以挂操作又可以挂服务,那到底是应该挂操作还是服务呢? 有个需求是要求一个动作可以在两个时点被触发 1.单据由下推或选单生成的时候: 2.点击单据界面功能菜单: 这样是不是需要做一个 ...

  3. [K/3Cloud] 树形单据体的应用说明

    1.BOSIDE制作单据,支持动态表单,单据,基础资料,报表等域模型. 2.添加列,和原来单据体一样. 3.设置主键列名,父级主键字段名,行类型字段名,节点图片字段名(没有可以为空)   4.运行时展 ...

  4. 光纤通信(codevs 1955)

    题目描述 Description 农民John 想要用光纤连通他的N (1 <= N <= 1,000)个牲口棚(编号1..N).但是,牲口棚位于一个大池塘边,他仅可以连通相邻的牲口棚.J ...

  5. 快速幂取模模板 && 51nod 1013 3的幂的和

    #include <iostream> #include <cstdio> #include <cmath> #include <vector> #in ...

  6. Sum-(最大子序列和)

    http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=652&pid=1003 题目大意: 给你一个序列,你随便找一 ...

  7. echarts模拟highcharts实现折线图的虚实转换

    多的不说直接上代码: <html><html lang="en"><head> <meta charset="utf-8&quo ...

  8. MongoDB小结24 - 索引简介2

    索引的名字 集合中每个索引都有一个字符串类型的名字,来唯一标识索引. 服务器通过名字来操作或者删除索引. 要注意的是,索引名有字符个数限制,所以索引创建时一定要用自定义的名字,如 db.user.en ...

  9. java文件工具类

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  10. 面试题之strcpy/strlen/strcat/strcmp的实现

    阿里的电面要我用C/C++实现一个字符串拷贝的函数,虽然以前写过 strcpy 的函数实现,但时间过去很久了,再加上有点紧张,突然就措手不及了.最后写是写出来了,但没考虑异常的情况,面试官好像很不满意 ...