final关键字

1-1 编译期常量

  • 定义:带有 ①编译时数值(区别于运行时数值)的 ②final 基本数据类型的量。
  • 注意:
  • 既是static又是final的量不一定是编译期常量;
public class NotCompileTimeConstant {
    static Random random = new Random(47);
    //Can't be a compile-time constant
    static final int number = random.nextInt(20);
}

如上代码中,number是用static final修饰的,但其值random.nextInt(20)是在运行时才会生成,所以其值不是编译时数值。因此number不是编译期常量。
2. 既是static又是final的量用大写字母表示,并使用下划线分割各个单词;
3. 一个既是static又是final的量只占据一段值不能改变的存储空间;

  • 作用:对于编译期常量,编译器可以将该常量带入任何可能用到它的计算式中,也就是说可以在编译期执行计算式,减轻了一些运行时负担。

1-2 常量

  • 用final修饰的数据称为常量,常量包含编译期常量;
  • 一般在定义未被static修饰的常量时就对其进行初始化(也可先声明其为空白final,在构造函数中再对其进行初始化),初始化后就不能再进行修改。而对于static修饰的常量来说,需要在定义时就对其初始化。
  • 当常量的类型是基本数据类型时,final使值恒定不变;但当常量的类型是引用时,final使引用自身恒定不变(指向不变),但是引用指向的值是可以变的;

1-3 空白final

  • 定义:空白final是指被声明为final但又未给定初始值的域(这里的域需要是非静态的);
  • 作用:空白final在关键字final的使用上提供了更大的灵活性,为此,一个类中的final域就可以做到根据对象的特性而有所不同,却又保持恒定不变的特性。
  • 注意:
  • 编译器会确保空白final在使用前被初始化;
  • 必须在域的定义处或者 每个构造器中用表达式对空白final进行赋值,否则编译器会报错。
public class BlankFinal {
    private final int i;//Error:Variable 'i' might not have been initialized
}
  • 探究:编译器是否会对类的空白final域进行默认初始化?
public class BlankFinal {
    private int i;

    public static void main(String[] args) {
        BlankFinal blankFinal = new BlankFinal();
        System.out.println(blankFinal.i);//i=0
    }
}

当i不为final时,在创建此类的对象时,会将其默认初始化为0

public class BlankFinal {
    private final int i;//Error:Variable 'i' might not have been initialized

    public static void main(String[] args) {
        BlankFinal blankFinal = new BlankFinal();
        System.out.println(blankFinal.i);
    }
}

//编译结果:java: 变量 i 未在默认构造器中初始化

而当i为空白final时,编译器检测到i为被初始化就会报错,此时可能还未进行创建对象。
* 所以不确定编译器是否会对空白final进行默认初始化,因为编译器会确保空白final在使用前必须被初始化,否则编译错误。但按理来说,如果能通过编译,那么final int i也会被默认初始化为0,因为默认初始化实际上是为对象分配一块内存空间,然后将该内存设置为二进制0值。

1-4 final参数

Java允许在参数列表中以声明的方式将参数指定为final,这意味着:如果参数类型是基本数据类型,那么你不能修改它的值;如果参数类型是引用类型,那么你不能修改引用的指向,但是可以修改引用指向的对象。

1-5 final方法

在方法的返回类型前加final关键字,可以防止任何继承类修改它的含义,即不能被覆盖(Override)。

类中所有的private方法都隐式地被指定为是final的。但由于在子类中无法取用private方法,所以其实无法覆盖private方法,所以对private方法添加final关键字没有什么额外的意义。

这里又引出了一个容易造成混淆的问题:如果试图去覆盖一个private方法(隐含是final的),似乎是可以的,而且编译器也不会给出错误信息:

如上代码编译器未报错。

而对于使用了final修饰的非private方法,如果在子类中覆盖了这些方法,编译器将会报错:

这是因为 “覆盖” 只会发生在 是基类接口一部分 的方法上。private方法不是基类接口的一部分(因为private方法只能在类内部访问),所以在子类中写一个与父类同样的方法时未发生”覆盖”,新写的这个方法被认为是在子类中生成了一个新的方法,所以编译器不会报错。而public,protected和具有包访问权限的方法都被认为是类接口的一部分,所以可以发生”覆盖”,在发生覆盖时发现被覆盖的方法是final的,按理来说是不能覆盖的,所以编译器报错。

1-6 final类

  • 当将某个类的整体定义为final时(通过将关键字final置于它的定义前),就表明了这个类不允许被继承。
  • 注意:
  • final类的域可根据个人意愿选择是否是final的,然后,由于final类禁止被继承,final类中的所有方法都隐式地被指定为final的,所以在final类中给方法添加final,并没有什么意义。

Original: https://www.cnblogs.com/certainTao/p/14653544.html
Author: certainTao
Title: final关键字

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585281/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Python eval()函数

    The eval() takes three parameters: expression – this string as parsed and evaluated …

    Linux 2023年6月8日
    0100
  • CA证书介绍与格式转换

    PKCS 公钥加密标准(Public Key Cryptography Standards, PKCS),此一标准的设计与发布皆由RSA资讯安全公司(英语:RSA Security…

    Linux 2023年6月6日
    092
  • Linus:“我删除了Linux,因为它就是个垃圾”

    1月 25日, Linus Torvalds 在 Linux 的 GitHub 仓库中提交了一个恶作剧 README页面,其备注名为《delete linux because it…

    Linux 2023年6月13日
    0107
  • 代码审计-PHP反序列化漏洞

    什么是序列化 序列化可以实现将对象压缩并格式化,方便数据的传输和存储。为什么要序列化?PHP 文件在执行结束时会把对象销毁,如果下次要引用这个对象的话就很麻烦,所以就有了对象序列化…

    Linux 2023年6月6日
    0120
  • Nginx禁止ip加端口访问

    使用 iptables 限制对应端口,再利用Nginx将80端口转发到对应端口 CentOS7默认的防火墙是 firewalle,先看看服务器中有没有安装 iptables [ro…

    Linux 2023年5月27日
    093
  • ansible用authorized_key模块批量推送密钥到受控主机实现免密登录

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月7日
    097
  • 测试代理的墙是否是通的

    curl -v -x 代理ip:端口 目的ip:端口通过代理访问对方wget “http://目的IP:端口” -e use_proxy=yes -e ht…

    Linux 2023年6月14日
    0107
  • .net core3.1 abp动态菜单和动态权限(动态菜单实现和动态权限添加) (三)

    我们来创建动态菜单吧 首先,先对动态菜单的概念、操作、流程进行约束:1.Host和各个Tenant有自己的自定义菜单2.Host和各个Tenant的权限与自定义菜单相关联2.Ten…

    Linux 2023年6月7日
    097
  • nand

    nand flash裸机编程第001节_NAND_FLASH操作原理第002节_NandFlash时序及初始化第003节_NandFlash的芯片id读取第004节_NandFla…

    Linux 2023年6月13日
    079
  • 【Leetcode】768. 最多能完成排序的块 II

    arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个”块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。 …

    Linux 2023年6月6日
    094
  • 【Prometheus+Grafana系列】监控MySQL服务

    前言 前面的一篇文章已经介绍了 docker-compose 搭建 Prometheus + Grafana 服务。当时实现了监控服务器指标数据,是通过 node_exporter…

    Linux 2023年6月7日
    096
  • docker 安装redis

    安装docker https://www.cnblogs.com/ximensama/p/14903105.html 安装redis https://www.cnblogs.com…

    Linux 2023年5月28日
    093
  • centos 8及以上安装mysql 8.0

    本文适用于centos 8及以上安装mysql 8.0,整体耗时20分钟内,不需要FQ 1.环境先搞好 systemctl stop firewalld //关闭防火墙 syste…

    Linux 2023年6月7日
    0111
  • shell加密

    如何保护自己编写的shell程序要保护自己编写的shell脚本程序,方法有很多,最简单的方法有两种:1、加密 2、设定过期时间,下面以shc工具为例说明: 一、下载安装shc工具s…

    Linux 2023年5月28日
    087
  • Laxcus集群操作系统应用软件:远程终端

    今天介绍一个Laxcus集群操作系统上的应用软件:远程终端。 远程终端提供和控制台相同的功能,都是由用户使用分布式命令操纵计算机集群上的服务器,处理各种各样的分布计算任务。所不同的…

    Linux 2023年6月6日
    078
  • srec_cat 常用参数的使用

    下面介绍映像文件工具 srec_cat 的使用,如何通过相关参数实现自己需要的功能。 文件类型 在输入文件和输出文件文件时要指明文件类型,常用的如: test.hex -intel…

    Linux 2023年6月7日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球