6、final finally finalize


1. final

1.1 修饰类

当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰

1.2 修饰方法

把方法锁定,以防止继承类对其进行更改。

1.3 修饰变量

final成员变量表示常量,只能被赋值一次,赋值后其值不再改变

在java中,String被设计成final类,那为什么平时使用时,String的值可以被改变呢?

字符串常量池是java堆内存中一个特殊的存储区域,当我们建立一个String对象时,假设常量池不存在该字符串,则创建一个,若存在则直接引用已经存在的字符串。当我们对String对象值改变的时候,例如 String a="A"; a="B" 。a是String对象的一个引用(我们这里所说的String对象其实是指字符串常量),当a=“B”执行时,并不是原本String对象("A")发生改变,而是创建一个新的对象("B"),令a引用它。

2. finally

finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。

特殊情况:

//1.只有与finally对应的try语句块得到执行的情况下,finally语句块才会执行。以上两种情况在执行try语句块之前已经返                     //回或抛出异常,所以try对应的finally语句并没有执行。
int i=1;
log.info("The Previous statement of try block");
i=i/0;
try {
  log.info("try block");
  return i;
}finally {
  log.info("finally block");
}
?
//执行结果
/**
* 2.当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句 *  块可能不会执行
*/
int i=1;
log.info("The Previous statement of try block");
try {
    log.info("try block");
    return i;
}catch (NullPointerException e){
    return 1;
}catch (StringIndexOutOfBoundsException e){
    return 2;
}catch (Exception e){
    return 3;
} finally{
    log.info("finally block");
    return 4;
}
?
/**
         * 3.当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行
         */
        int i=1;
        log.info("The Previous statement of try block");
        try {
            log.info("try block");
            return i;
        }finally {
            log.info("finally block");
        }
/**
         * 4.首先finally语句在改代码中一定会执行,从运行结果来看,每次return的结果都是4(即finally语句),仿佛其他return语句被屏蔽掉了。
         * 事实也确实如此,因为finally用法特殊,所以会撤销之前的return语句,继续执行最后的finally块中的代码。
         */
        int i=1;
        log.info("The Previous statement of try block");
        try {
            log.info("try block");
            return i;
        }catch (NullPointerException e){
            return 1;
        }catch (StringIndexOutOfBoundsException e){
            return 2;
        }catch (Exception e){
            return 3;
        } finally{
            log.info("finally block");
            return 4;
        }

3. finalize

  finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。 特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。   使用finalize还需要注意一个事,调用super.finalize();

  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。