详细对比java中的 final,finally, finalized关键字

final

在java中,final可以用来修饰类,方法和变量(成员变量或局部变量)。下面将对其详细介绍。

1. 修饰类

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

final类中所有的成员都会隐式的定义为final方法。

2 修饰方法

使用final方法的原因:

把方法锁定,以防止继承类对其进行更改。
  
final方法意味着“最后的、最终的”含义,即此方法不能被重写。

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

3 修饰变量

final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。类似于C中的const。

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

final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。

当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。

在java中,String被设计成final类,那为什么平时使用时,String的值可以被改变呢?
在这里插入图片描述在这里插入图片描述
  字符串常量池是java堆内存中一个特殊的存储区域,当我们建立一个String对象时,假设常量池不存在该字符串,则创建一个,若存在则直接引用已经存在的字符串。当我们对String对象值改变的时候,例如 String a=“A”; a=“B” 。a是String对象的一个引用(我们这里所说的String对象其实是指字符串常量),当a=“B”执行时,并不是原本String对象(“A”)发生改变,而是创建一个新的对象(“B”),令a引用它。

finally

详细了解java异常处理<-- <–

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

1.finally不执行的两种情况

  • 只有与finally对应的try语句块得到执行的情况下,finally语句块才会执行。如果try语句块之前已经返回或抛出异常,try对应的finally语句并没有执行。
  • 在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行。

finalize

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

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

package 测试;
class J_Book
{
    public int m_id; // 书的编号

    public J_Book( int i )
    {
        m_id = i;
    } // J_Book构造方法结束

    protected void finalize( )
    {
        switch (m_id)
        {
        case 1:
            System.out.print( "《飘》" );
            break;
        case 2:
            System.out.print( "《Java程序设计教程》" );
            break;
        case 3:
            System.out.print( "《罗马假日》" );
            break;
        default:
            System.out.print( "未知书籍" );
            break;
        } // switch语句结束
        System.out.println( "所对应的实例对象存储单元被回收" );
    } // 方法finalize结束
} // 类J_Book结束

public class J_Finalize
{
    public static void main(String args[ ])
    {
        J_Book book1= new J_Book( 1 );
        new J_Book( 2 );
        new J_Book( 3 );
        System.gc( ); // 申请立即回收垃圾
    } // 方法main结束
} // 类J_Finalize结束

输出结果
在这里插入图片描述

发布了79 篇原创文章 · 获赞 514 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/i6223671/article/details/89288242