在 Java 中,声明类、变量和方法时,可使用关键字 final 来修饰。final 所修饰的数据具有“终态”的特征,表示“最终的”意思。具体规定如下:

  • final 修饰的类不能被继承。
  • final 修饰的方法不能被子类重写。
  • final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
  • final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
  • final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。

final 一般用于修饰那些通用性的功能、实现方式或取值不能随意被改变的数据,以避免被误用,例如实现数学三角方法、幂运算等功能的方法,以及数学常量π=3.141593、e=2.71828 等。

事实上,为确保终态性,提供了上述方法和常量的 java.lang.Math 类也已被定义为final 的。

需要注意的是,如果将引用类型(任何类的类型)的变量标记为 final,那么该变量不能指向任何其它对象。但可以改变对象的内容,因为只有引用本身是 final 的。

如果变量被标记为 final,其结果是使它成为常数。想改变 final 变量的值会导致一个编译错误。下面是一个正确定义 final 变量的例子:

1 public final int MAX_ARRAY_SIZE = 25; // 常量名一般大写

常量因为有 final 修饰,所以不能被继承。

请看下面的代码:

public final class Demo{
public static final int TOTAL_NUMBER = 5;
public int id;
public Demo() {
// 非法,对final变量TOTAL_NUMBER进行二次赋值了
// 因为++TOTAL_NUMBER相当于 TOTAL_NUMBER=TOTAL_NUMBER+1
id = ++TOTAL_NUMBER;
}
public static void main(String[] args) {
final Demo t = new Demo();
final int i = 10;
final int j;
j = 20;
j = 30; // 非法,对final变量进行二次赋值
}
}

final 也可以用来修饰类(放在 class 关键字前面),阻止该类再派生出子类,例如 Java.lang.String 就是一个 final 类。这样做是出于安全原因,因为要保证一旦有字符串的引用,就必须是类 String 的字符串,而不是某个其它类的字符串(String 类可能被恶意继承并篡改)。

方法也可以被 final 修饰,被 final 修饰的方法不能被覆盖;变量也可以被 final 修饰,被 final 修饰的变量在创建对象以后就不允许改变它们的值了。一旦将一个类声明为 final,那么该类包含的方法也将被隐式地声明为 final,但是变量不是。

被 final 修饰的方法为静态绑定,不会产生多态(动态绑定),程序在运行时不需要再检索方法表,能够提高代码的执行效率。在Java中,被 static 或 private 修饰的方法会被隐式的声明为 final,因为动态绑定没有意义。

由于动态绑定会消耗资源并且很多时候没有必要,所以有一些程序员认为:除非有足够的理由使用多态性,否则应该将所有的方法都用 final 修饰。

这样的认识未免有些偏激,因为 JVM 中的即时编译器能够实时监控程序的运行信息,可以准确的知道类之间的继承关系。如果一个方法没有被覆盖并且很短,编译器就能够对它进行优化处理,这个过程为称为内联(inlining)。例如,内联调用 e.getName() 将被替换为访问 e.name 变量。这是一项很有意义的改进,这是由于CPU在处理调用方法的指令时,使用的分支转移会扰乱预取指令的策略,所以,这被视为不受欢迎的。然而,如果 getName() 在另外一个类中被覆盖,那么编译器就无法知道覆盖的代码将会做什么操作,因此也就不能对它进行内联处理了。

参考:https://www.cnblogs.com/Coda/p/4423592.html

《Java基础知识》Java final关键字:阻止继承和多态的更多相关文章

  1. Java基础知识回顾之三 ----- 封装、继承和多态

    前言 在上一篇中回顾了java的修饰符和String类,这篇就来回顾下Java的三大特性:封装.继承.多态. 封装 什么是封装 在面向对象程式设计方法中,封装是指一种将抽象性函式接口的实现细节部份包装 ...

  2. JAVA基础知识|java虚拟机(JVM)

    一.JVM简介 java语言是跨平台的,兼容各种操作系统.实现跨平台的基石就是虚拟机(JVM),虚拟机不是跨平台的,所以不同的操作系统需要安装不同的jdk版本(jre=jvm+类库:jdk=jre+开 ...

  3. Java基础知识之this关键字知识讲解

    this关键字这里对java中this关键字的基础知识进行讲解,希望对热爱java的小伙伴有帮助!! /* this关键字代表了所属函数的调用者对象. this关键字的作用: 1. 如果存在同名成员变 ...

  4. java基础篇 之 final关键字

    ​ final,字面上是最终的意思,通常来说,我们用它来作为修饰符的时候,都是代表"这是无法改变的"的意思.不想改变可能出与两种理由:设计或效率.由于这两个原因相差甚远,所以我们在 ...

  5. JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)

    1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...

  6. java基础知识——Java的定义,特点和技术平台

    (作者声明:对于Java编程语言,很多人只知道怎么用,却对其了解甚少.我也是其中一员.所以菜鸟的我,去查询了教科书以及大神的总结,主要参考了<Java核心技术>这本神作.现在分享给大家!) ...

  7. [java基础知识]java安装步骤

    jre:  java运行环境.  jre =  java虚拟机 + 核心类库(辅助java虚拟机运行的文件).如果只是运行java程序,只需要安装jre.    jdk: java开发工具集   jd ...

  8. Java基础知识总结--final、finally、finalize的区别

    谈谈final.finally.finalize的区别 1.final修饰符:如果一个类被声明为final,意味着这个类不能再被派生出新的子类,不能作为父类被别的类继承.因此,一个类不能即被声明为ab ...

  9. Java基础知识之常见关键字(1)

    static 特点: 随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用 注意点: 静态方法只能访问静态方法 但是非静态成员可以直接访问静态成员 静态方法中不可以使用this , ...

  10. Java基础知识之常见关键字以及概念总结

    static 特点: 随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用 使用注意: 静态方法只能访问静态成员 但是非静态成员可以直接访问静态成员 静态方法中不可用使用this, ...

随机推荐

  1. web前端开发面试题(Vue.js)

    1.active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么获取传过来的动态参数?  ...

  2. Django安装和使用---python(3)

    一.安装 一般使用cmd 安装就可以 pip install django // 这是最新版本 pip install django==2.0.2(自定义安装2.0.2版本) 手动安装通过下载方式 d ...

  3. 新闻实时分析系统-Hadoop2.X HA架构与部署

    1.HDFS-HA架构原理介绍 hadoop2.x之后,Clouera提出了QJM/Qurom Journal Manager,这是一个基于Paxos算法实现的HDFS HA方案,它给出了一种较好的解 ...

  4. 【RocketMQ源码学习】- 5. 消息存储机制

    前言 面试官:你了解RocketMQ是如何存储消息的吗?我:额,,,你等下,我看下这篇文字, (逃 由于这部分内容优点多,所以请哥哥姐姐们自备茶水,欢迎留言! RocketMQ存储设计是高可用和高性能 ...

  5. 【Android - 组件】之IntentFilter的匹配规则

    我们知道,Activity的启动模式分为两种,分别是显式启动和隐式启动.显式启动需要明确的指定被启动的对象的组件信息,包括包名和类名:而隐式启动需要 Intent 能够匹配目标组件的 IntentFi ...

  6. FaceBook的秘钥散列获取

    随笔记录 先下载OpenSSL工具 在C盘创建一个openssl,将下好的OpenSSL工具解压到这里 将你的 .keystore文件复制到JAVA JDK 文件夹的bin目录里面(C:\Progra ...

  7. shell介绍、命令历史、命令补全和别名、通配符、输入输出重定向

    第5周第5次课(4月20日) 课程内容: 8.1 shell介绍8.2 命令历史8.3 命令补全和别名8.4 通配符8.5 输入输出重定向 8.1 shell介绍 使用yum+管道方式查看zsh和ks ...

  8. 对python的初步了解

    一,Python简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具 ...

  9. mysql 替换 tab 键 (\t)

    update t_instance set instance_name = replace(instance_name,'\t','') , host_name = replace(host_name ...

  10. #华为云·寻找黑马程序员#微服务-你真的懂 Yaml 吗?

    在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的. "天哪,这可是20年前的东西了,我居然还在用 Properties. ...