面试题:谈谈你对 final 关键字以及 final、finally、finalize的区别

final 关键字

final:代表最终的、不可变的

常用的四种方法:

1、可以用来修饰一个类

2、可以用来修饰一个方法

3、可以用来修饰一个局部变量

4、可以用来修饰一个成员变量

一、修饰一个类

当一个类被 final 修饰时,这个类不能有任何子类(断子绝孙)

格式:

public final class 类名称 {
    // ......
}

注意:如果一个类是 final 的,那么其中所有的成员方法都无法进行覆盖重写(因为没有儿子)

public final class Fu {
   
}
// Zi 类继承 Fu ,出现报错
public class Zi extends Fu {
    
}

常见的 final 类:String类

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    // .....
}

注意: 在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类

二、修饰一个方法

当 final 关键字用来修饰一个方法的时候,这个方法就是最终方法,不能被覆盖重写。但是这个方法任然可以被继承

格式:

修饰符 final 返回类型 方法名称(参数列表) {
    // 方法体
}
public  class Fu {
    public final void function(){
        System.out.println("刘雨昕");
    }
}

public class Zi extends Fu {
    // 报错,子类不可以覆盖父类的 final 方法
     public final void function(){
    }
}
public  class Fu {
    public final void function(){
        System.out.println("刘雨昕");
    }
}
public class Zi extends Fu {
    public static void main(String[] args) {
        Zi zi = new Zi();
        // 父类的 final 方法,子类任然可以调用
        Zi.functuon();// 刘雨昕
    }
}

注意

1、对于类、方法来说, abstract关键字和final关键字不能同时使用。

2、 如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。

三、修饰一个局部变量

一旦使用final用来修饰局部变量,那么这个变量就不能进行更改。
“—次赋值,终生不变“

final int num = 100;
num = 200;// 错误
num = 100;// 错误
final int num;
num = 100;// 正确!!!只要保证有唯一一次赋值即可

对于基本类型来说,不可变说的是变量当中的数据不可改变

对于引用类型来说,不可变说的是变量当中的地址值不可改变

final Student s = new Studnet("刘雨昕");
// s = new Studnet("刘妞妞");// 错误
System.out.println(s.getName());// 刘雨昕
s.setName("刘妞妞");
System.out.println(s.getName());// 刘妞妞
四、修饰一个成员变量

对于成员变量,如果使用 final 修饰的时候,那么这个变量也是不可变的

1、成员变量具有默认值,所以用了 final 之后鼻祖手动赋值,不会再给默认值了

public class Student {
    private final String name;// 错误
}

2、对于 final 的成员变量,要么使用直接赋值,要么通过构造方法赋值。(二选一)

3、必须保证类中所有的重载的构造方法,都最终会对 final 的成员变量进行赋值

五、final 关键字的好处

1、 final关键字提高了性能。JVM 和 Java 应用都会缓存final变量。

2、 final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。

3、 使用final关键字,JVM 会对方法、变量及类进行优化。

六、常见面试题

讲讲 final 和 finally 和 finalize() 的区别?

final:可以修饰类、方法、局部变量、成员变量

前面已经讲过了

finally: java的一种异常处理机制

finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管有无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。

public static String m() {
    try {
        int a = 10;
        return "try-return";
    }finally {
        System.out.println("finally");
        return "finally-return ";
    }
}

public static void main(String[] args) {
    System.out.println(m());
}

打印结果:

finally
finally-return 

为什么还会打印finally呢?

首先finally语句在改代码中一定会执行,从运行结果来看,仿佛其他return语句被屏蔽掉了。

事实也确实如此,因为finally用法特殊,所以会撤销之前的return语句,继续执行最后的finally块中的代码。

finalize():Java中的一个方法名。

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

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

七、总结
  • final关键字可以用于成员变量、本地变量、方法以及类。

  • final类不能被继承

  • final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。

  • 不能够对final变量再次赋值

  • 在匿名类中所有变量都必须是final变量

  • 子父类之间final方法不能被重写

  • final关键字不同于finally关键字,后者用于异常处理

  • final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法

  • 接口中声明的所有变量本身是final的

  • final和abstract这两个关键字是反相关的,final类就不可能是abstract的

  • 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”

  • 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化

  • 按照Java代码惯例,final变量就是常量,而且通常常量名要大写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值