在 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. 扛把子组20191107-8 beta week 2/2 Scrum立会报告+燃尽图 07

    此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9960 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...

  2. html基础——div/span

    div是一个块标签/盒子标签,单独占据一行 span不会占据一块,一般是用来修改某几个文字的格式 比如一行字,需要将每一句的首字母大写,就可以使用span标签 如果是要将一个段落的字加样式,两个都可以 ...

  3. 2019-10-12,html+php+mysql简单留言板,作业

    php+mysql简易留言板,实现注册,登录,注销,查看留言,删除留言 1,index.html登录页面 代码: <!doctype html> <html> <head ...

  4. python爬虫项目-一见倾心壁纸

    方法1 import re import urllib import urllib.request def getHtml(url): page = urllib.request.urlopen(ur ...

  5. day 13 生成器函数 表达式 推导式

    今日主要内容 1. 生成器和生成器函数 生成器的本质就是迭代器 生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 2. 生成器函数: 函数中包含了yield ...

  6. Spring(Bean)4 配置数据源、连接池

    <!-- 配置数据源 Mysql c3p0: 连接池. <bean id="dataSource" class="com.mchange.v2.c3p0.Co ...

  7. 【Android - 控件】之MD - NavigationView的使用

    NavigationView是Android 5.0新特性——Material Design中的一个布局控件,可以结合DrawerLayout使用,让侧滑菜单变得更加美观(可以添加头部布局). Nav ...

  8. CentOS 7 Keepalive 脚本不执行解决

    目录 问题 问题一 括号问题 问题二 脚本名称问题 问题 起因是在测试部署 Altls + Keepalive 高可用读写分离,测试停止Atlas服务的时候,发现Keepalive不会自动主从切换,就 ...

  9. 【集合系列】- 深入浅出分析HashMap

    一.摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap.LinkedHashMap.TreeMap.IdentityHashMap.WeakHashMap.Hashtable.Pro ...

  10. Linux运维的第一周总结

    这个阶段主要学习 Linux 运维技术,包括 Linux 基本操作.Bash 编程.应用服务部署.数据库服务部署.日志管理.系统监控等. 第1周: Linux基础本周学习 Linux 基本操作.用户与 ...