深入理解final关键字(详解)

深入理解final关键字(详解)提及 final 关键字都会想到一个常见的面试题就是 final finally finalize 区别在这里我们来简单回忆一下这三者的区别 final Final 用于修饰类 成员变量和成员方法 final 修饰的类 不能被继承 String StringBuilde StringBuffer Math 不可变类 其中所有的方法都不能被重写 这里需要注意的是不能被重写 但是可以被重载 这

  • final: Final用于修饰类、成员变量和成员方法。final修饰的类,不能被继承(String、StringBuilder、StringBuffer、Math,不可变类),其中所有的方法都不能被重写(这里需要注意的是不能被重写,但是可以被重载,这里很多人会弄混),所以不能同时用abstract和final修饰类(abstract修饰的类是抽象类,抽象类是用于被子类继承的,和final起相反的作用);Final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;Final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容是允许改变的。

我们来深入理解一下被final修饰的类、方法、变量

  1. final修饰的类
    在这里插入图片描述

  1. 被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)); } } 
  1. 变量a指的是字符串常量池中的 xiaomeng2;
  2. 变量 b 是 final 修饰的,变量 b 的值在编译时候就已经确定了它的确定值,换句话说就是提前知道了变量 b 的内容到底是个啥,相当于一个编译期常量;
  3. 变量 c 是 b + 2得到的,由于 b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(xiaomeng)来进行计算,所以 c 生成的也是一个常量,a 是常量,c 也是常量,都是 xiaomeng2 而 Java 中常量池中只生成唯一的一个 xiaomeng2 字符串,所以 a 和 c 是相等的!
  4. d 是指向常量池中 xiaomeng,但由于 d 不是 final 修饰,也就是说在使用 d 的时候不会提前知道 d 的值是什么,所以在计算 e 的时候就不一样了,e的话由于使用的是 d 的引用计算,变量d的访问却需要在运行时通过链接来进行,所以这种计算会在堆上生成 xiaomeng2 ,所以最终 e 指向的是堆上的 xiaomeng2 , 所以 a 和 e 不相等。
    总得来说就是:a、c是常量池的xiaomeng2,e是堆上的xiaomeng2

然后我们来看一下被final修饰的引用变量和基本变量有什么不同:

然后我们总结一下使用final关键字的好处:

  1. final方法比非final快一些
  2. final关键字提高了性能。JVM和Java应用都会缓存final变量。
  3. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
  4. 使用final关键字,JVM会对方法、变量及类进行优化。
  • Finally:

通常和try catch搭配使用,保证不管有没有发生异常,资源都能够被释放(释放连接、关闭IO流)

当try中有return时执行顺序:return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)

  • 情况一(try中有return,finally中没有return)

在这里插入图片描述

“return num += 80”被拆分成了“num = num+80”和“return num”两个语句,线执行try中的“num =num+80”语句,将其保存起来,在try中的”return num“执行前,先将finally中的语句执行完,而后再将90返回。

  • 情况二(try和finally中均有return)

在这里插入图片描述

try中的return被”覆盖“掉了,不再执行。

  • 情况三(finally中改变返回值num)

在这里插入图片描述

虽然在finally中改变了返回值num,但因为finally中没有return该num的值,因此在执行完finally中的语句后,test()函数会得到try中返回的num的值,而try中的num的值依然是程序进入finally代码块前保留下来的值,因此得到的返回值为10。并且函数最后面的return语句不会执行。

  • 另外一种情况:将num的值包装在Num类中

在这里插入图片描述

总结:

try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:

情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。

情况二:如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。


  • Finalize:

Finalize是object类中的一个方法,子类可以重写finalize()方法实现对资源的回收。垃圾回收只负责回收内存,并不负责资源的回收,资源回收要由程序员完成,Java虚拟机在垃圾回收之前会先调用垃圾对象的finalize方法用于使对象释放资源(如关闭连接、关闭文件),之后才进行垃圾回收,这个方法一般不会显示的调用,在垃圾回收时垃圾回收器会主动调用。

关于我

觉得文章不错请扫码关注我吧

weichat

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212827.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:10
下一篇 2026年3月18日 下午7:11


相关推荐

  • SPI转can芯片mcp2515[通俗易懂]

    SPI转can芯片mcp2515[通俗易懂]开发环境CPU:RK3399ARCH:aarch64OS:ubuntu18.04mcp2515芯片相关信息修改设备树文件文件路径:kernel/arm64/boot/dts/rockchip/rk3399.dts增加spi节点,具体增加那个spi节点,参考原理图上mcp5215和rk399的连接方式。此处以spi1节点为例。在spi1节点中还需天机can节点,mcp2515需要使用的其它硬件资源,如中断引脚、复位引脚。示例如下:kernelconfig…

    2025年8月18日
    5
  • C#实现简单网页

    C#实现简单网页⑴创建ASP.NET网站新建MyWebSite网站,添加一个WebForm1网页,其中包含一个文本框TextBox1一个按钮Button1(计算)和一个标签Label1(””)。在文本框中输入一个数,当点击“计算”按钮时,在标签中显示此数的平方根。WebForm1.aspx文件内容如下:<%@PageLanguage=”C#”AutoEventWireup=”true…

    2022年10月13日
    3
  • 深入理解Java类加载器(1):Java类加载原理解析

    深入理解Java类加载器(1):Java类加载原理解析1      基本信息每个java开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的类加载机制是java技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚拟机的连接模型和java语言的动态性

    2022年8月11日
    7
  • CSS加JS实现网页返回顶部功能

    CSS加JS实现网页返回顶部功能最近在设计自己的博客,前端页面在内容很多的时候往下拖动会有滚动条。通常我们都需要一个返回顶部的功能来实现快速来到网页顶部。当然实现方式不止一种,这里我采用的最实用的一种。使用CSS+Jquery方式代码量相对较少,容易理解。实现原理1.我们需要再DOM中添加自己的DIV,里面包含一个a标签,a标签里面包含两个img标签用于存放返回顶部的图片。2.添加必要的CSS样式3.然后…

    2022年7月15日
    17
  • yolov5算法详解(yolov3算法图解)

    全网YOLO最详讲解,从v1到v5!从小白到大佬!

    2022年4月12日
    823
  • lxml.etree去除子节点

    lxml.etree去除子节点

    2021年9月11日
    155

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号