Java中Final、Finally、Finalize三者概述

Final

Java中的一个保留关键字,可修饰声明的变量、方法和类

对变量、方法、类的声明

  • final修饰类时,该类没有子类,即不能被继承作为父类;

  • final修饰方法

    • 将方法锁定,防止任何继承类修改其含义
    • 提高效率:早期Java版本中,final方法转为内嵌调用

    (如果方法太庞大了,可能性能提升并不明显甚至看不到提升)

  • final修饰变量

public class Main {
   public static void main(String[] args) {
       String a = "LPB2";
       final String b = "LPB";
       String d = "LPB";
       String c = b + 2;
       String e = d + 2;
       System.out.println((a == c));
       System.out.println((a == e));
   }
}
/**
 *输出结果:
 *	true 
 * 	false
 */

字符串a是字符串常量池中的LPB2;

变量b是用final修饰的,在编译时候其值就已经确定了,就是说已经提前知道了b的内容,相当于一个编译期常量;

变量c是b+2生成的,相当于直接使用b的原始值(即LPB)进行运算,得到的也是一个常量,而Java中常量池只生成唯一的一个LPB2,故a和c都指向同一个常量,输出true

变量d 和a一样是指向常量池的值

变量e是d+2生成的,但其中的d并没有final修饰,在使用d的时候并不知道d的值是什么,所以在计算e的过程中,使用的d是d的引用计算,变量d的访问需要在运行的时候通过链接进行,获取d指向的常量池中的值进行计算,且计算后生成的LPB2是在堆上的。即e指向的是堆上的LPB2,所以a和e不相等。

注:

  1. Java中的 == 比较判断两边是否指向同一个地址。不同则返回false;
  1. final修饰的普通变量不可改变;
  2. final修饰的引用变量引用不可变,引用对象的内容(如类的实例对象中某个基本数据类型的值)可以改变;

Finally{}块

​ 在Java编程中,使用try语句的时候,对于一段代码,程序员会希望无论try语句中的异常是否抛出,这段代码都能得到执行,则可以将这段代码置于异常抛出处理程序之后的finally子句中。

​ 对于没有垃圾回收和析构函数自动调用机制的语言来说,finally非常重要,保证在finally中对try块运行占据的内存进行释放,但Java有垃圾回收机制,故一般无须考虑内存释放的问题。

​ finally在Java中的主要作用是将除内存之外的资源恢复到它们的初始状态,包括:

  • 已经打开的文件和网络连接;
  • 在屏幕上画的图形;
  • 外部世界的某个开关;

Finalize()方法

​ 众所周知,Java中有垃圾回收器负责回收无用对象占据的内存资源。但是,垃圾回收器只知道释放那些经过new分配的对象,并没有释放不使用new声明的对象占据的内存。

​ Java为了应对这种情况,在超类Object类中定义finalize()方法,并允许在类中重写finalize()方法,提供内存资源回收时对实例对象的其他资源回收,如关闭文件等。

在《Java编程思想(第四版)》中对finalize()方法工作原理的描述如下:

一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

注意:这里有必要区分下Java中的finalize()方法和C++中的析构函数之间的区别:

  • 在C++中,销毁对象必须用到析构函数,一般情况下对象是一定会被销毁的,
  • Java并未提供“析构函数”或者类似的概念,Java中的对象并非总是被垃圾回收

猜你喜欢

转载自blog.csdn.net/weixin_40849588/article/details/87627689