写在前面:这是一个软件菜鸟写的笔记,比起权威他更愿意相信自己验证的结果,本文大部分内容与结果都源于此,如有错误,请多斧正。
final、finalize和finally是Java中常用的三种关键字,下面我就来对这三个关键字进行一下简单的介绍和辨析。
一、final关键字
final关键字可以用来修饰变量(整体变量和局部变量)、当final修饰类时,相当于说明该类不能作为父类被子类继承,也就是说如果你不想让这个类被子类修改就将他用final修饰。要注意当一个类被final修饰后其所有的方法都会被隐式的定为final方法。
public final class OldClass {
public OldClass() {
System.out.println("OldClass()");
}
public OldClass(String str) {
System.out.println("OldClass(str)" + str);
}
}
public class SubCLass extends OldClass{ //继承报错
public SubCLass() {
System.out.println("SubCLass()");
}
public SubCLass(String str) {
super("Ano Hello");
System.out.println("SubCLass(String str)" + str);
}
}
当final修饰方法时,禁止该方法被以任何形式修改和覆盖,否则报错。
当final修饰变量时,也是应用最多的情形,该变量将被编译器理解为常量,不可被直接更改或被继承方法等间接更改,如:
public class FinalData {
private final int num1 = 2000;
public FinalData(int num) {
this.num1 = num; //报错,The final field FinalData.num1 cannot be assigned,需去掉final才可
System.out.println(this);
System.out.println(num1);
}
}
public class FinalTest {
public static void main(String[] args) {
final int num = 0;
num = new FinalData().getFinalData(50); //报错 The final local variable num cannot be assigned. It must be blank and not using a compound assignment
}
public class FinalTest {
public static void main(String[] args) {
final FinalData finalNum = new FinalData(2000);
finalNum = new FinalData(5000); //报错,finalNum必须为空值(未被赋值,只被声明)或复合赋值(晚上整理)
finalNum.finalNNum = 6;
}
}
由此可见,final修饰的变量是一不可被二次修改的确定值。但在网上看到一种说法,当final用于修饰方法参数时该参数便被定死,引起了我的兴趣:
public class FinalData {
int finalNNum;
public FinalData(final int num) {
num = 20; //报错,num必须为空值或者复合赋值后的值
this.finalNNum = num;
}
}
还是之前的函数,只是将方法参数中的num加上了final关键字。 嗯,看来网上说的是对的。嗯?不全对?既然对num直接赋值不行,那通过将num作为某值的地址改变其指向的值呢?
public class FinalData {
int finalNNum;
public FinalData( int num) {
this.finalNNum = num;
}
}
public class FinalTest {
public static void main(String[] args) {
final FinalData finalNum;
finalNum = new FinalData(2000);
finalNum .finalNNum++;
System.out.println(finalNum.finalNNum);
}
}
输出为2001。
综上所述,final修饰的类不可被继承,进而保证了该类的安全性,却限制了他的被扩展性,适合安全性比较高的类与方法。final修饰的变量,包括几种基本数据类型与String类型,一旦进入编译便会被作为常量处理,无法更改,但可以更改其指向值。
二、finalize方法
想了解finalize()首先需要了解什么是GC。
GC(Garbage colection)垃圾回收机制是Java中存在的、区别于其他语言的一项机制。众所周知,当我们new出并使用完一个对象之后并没有编写关于内存回收的代码,但程序和计算机并没有因为碎片垃圾过多而崩溃,这些全是GC的功劳。一般new出来的对象使用GC自动回收就好,finalize()相当于对程序员提供了一个释放内存的方法,主要作用是回收通过特殊渠道申请的特殊资源,比如Socket。
这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法在垃圾收集器删除对象之前对这个对象调用,如果因为调用过一次导致后来需要关闭的资源无法再次调用finalize()方法,会引起重大的错误,所以绝对不要直接调用。
下为引用:
Java语言不保证哪个线程会调用finalize方法。但是却保证那个调用finalize方法的线程,会在finalize被调用的时候持有任何用户可见的同步锁。如果finalize方法中抛出了一个没有被catch的异常,这个异常会被忽略,finalize方法会中止。
一个对象的finalize方法被调用之后,这个对象就不可以被任何活动的线程再次引用了,即使出现异常终止也一样,这个对象也不能再进行任何的操作,包括被那些已经执行finalize方法的对象或者类,直到被Java虚拟机回收。
三、finally关键字
finally关键字书写与try{...}catch{...}之后,作为一条无条件执行的语句存在着。即,无论执行了几次try{....}catch{.....},try了什么,catch了什么,finally中的语句块都会被无条件执行。