,文章

[摘]final、finally与finalize的区别

文章目录

final

在Java中final可以用来修饰类,方法和变量(成员变量和局部变量)。

修饰类

当用final修饰类时,表示该类不能被其他类继承。

同时,final修饰的类中的方法和都会隐式的定义为final 方法。

修饰方法

final修饰的方法表示不能被重写。

注意:若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。

class A{
    private final void getName(){

    }
}

public class B extends A{
    public void getName(){

    }

    public static void main(String[]args){
        System.out.println("OK");
    }
}
修饰变量

final 修饰的变量表示常量,只能被赋值一次,赋值后的值不会改变。

当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。

finally

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

以上引用于《final、finally与finalize的区别》。哈哈哈,第一次看到很震惊,为啥有错呢!!!

然后跟着该文章的作者把他的代码敲了一波,发现确实存在一定的问题。

代码一
    /**
     * Test One
     *
     * @return
     */
    private static int TestOne() {
        int i = 1;
        Log.d(TAG, "test start: ");
        i = i / 0; //这里会抛出异常
        try {
            Log.d(TAG, "Test try: ");
            return i;
        } catch (Exception e) {
            e.printStackTrace();
            Log.d(TAG, "Test catch: ");
        } finally {
            Log.d(TAG, "Test finally: ");
        }
        Log.d(TAG, "Test end(0): ");
        return 0;
    }

这个其实不算,因为还没有进入try catch语句中。

不过原文作者再来一个demo,这个确实是我没想到过的。

代码二
    private static int TestTwo() {
        int i = 1;
        Log.d(TAG, "test start: ");
        try {
            Log.d(TAG, "Test try: ");
            System.exit(0); //退出程序
            return i;
        } catch (Exception e) {
            e.printStackTrace();
            Log.d(TAG, "Test catch: ");
        } finally {
            Log.d(TAG, "Test finally: ");
        }
        Log.d(TAG, "Test end(0): ");
        return 0;
    }

这个我测试了一下,在try catch中,但最后没有走finally。

system.exit(int status) 正常退出 status为0时为正常退出程序,也就是结束当前正在运行中的java虚拟机。 非正常退出 status为非0的其他整数(包括负数,一般是1或者-1),表示非正常退出当前程序。

如上面说的,system.exit(int status)会终止Java虚拟机,也就是后面的无法执行了。

finalize

finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。

特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。

使用finalize还需要注意一个事,调用super.finalize();

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

来源

  1. final、finally与finalize的区别
  2. system.exit(1) 和 system.exit(0)用法与作用
发表评论