final finally 和 finalize的区别
final修饰符(关键字)
概念
被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。
特点
-
被final修饰的类不可以被继承
-
被final修饰的方法不可以被重写
-
被final修饰的变量不可以被改变,如果修饰引用,那么表示引用不可变,引用指向的内容可变.
补充一下引用数据类型(引用数据类型分3种:类,接口,数组)
public class FinalTest {
public static void main(String[] args) {
final StringBuffer a = new StringBuffer("夜僚🦅");
//Cannot assign a value to final variable 'a'
//a=new StringBuffer("");
//但是,但是,执行如下语句则可以通过编译
a.append("+CK");
}
}
夜僚🦅+CK
Process finished with exit code 0
- 被final修饰的方法,JVM会尝试将其内联,以提高运行效率
- 被final修饰的常量,在编译阶段会存入常量池中
finally是区块标志
概念
在异常处理时提供finally块来执行任何清除操作,不管有没有异常被抛出、捕获,finally块都会被执行(这里的代码只要 JVM 不关闭都能执行)。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。
注意
具体看JAVA异常_夜僚鹰的博客-CSDN博客中的finally块和return
finally块没有处理异常的能力。处理异常的只能是catch块。
在同一try…catch…finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。
在同一try…catch…finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。
当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。
finally中的return 会覆盖 try 或者catch中的返回值
finally中的return会抑制(消灭)前面try或者catch块中的异常
finally中的异常会覆盖(消灭)前面try或者catch中的异常
finalize是方法名
概念
java技术允许使用finalize方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize方法以整理系统资源或者被执行其他清理工作。
用法
finalize() 是Java中Object的一个protected方法.返回值为空,当该对象被垃圾回收器回收时,会调用该方法.
- finalize不等价于c++中的析构函数;
- 对象可能不被垃圾机回收器回收;
- 垃圾回收不等于析构;
- 垃圾回收只与内存有关;
- 垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的;
- 程序强制终结后,那些失去引用的对象将会被垃圾回收.(System.gc())
finalize()的用途:比如当一个对象代表了打开了一个文件,在对象被回收前,程序应该要关闭该文件,可以通过finalize函数来发现未关闭文件的对象,并对其进行处理.
public class FileOperator {
private boolean closed = false;
void close(){
this.closed = true;
}
@Override
protected void finalize(){//当垃圾回收器企图回收本对象时,会调用该方法,该方法是重写父类的方法的
if(!closed){//如果该书没有被签入,
System.out.println("Error: A File was not closed . Name:" + this);
this.closed = true;
}
}
public static void main(String[] args) {
FileOperator fileOperator = new FileOperator();//有引用的对象,不会被虚拟机回收
new FileOperator();//匿名对象,会被虚拟机回收
System.gc();//强制进行终结动作
}
}