上一篇地址:整理好了!2024年最常见 100 道 Java基础面试题(十)-CSDN博客
二十一、final 关键字有哪些用法?
final
关键字在Java中有几个不同的用途:
-
最终变量: 当用
final
修饰一个变量时,这个变量变成了常量,它的值在初始化之后不能被改变。对于基本数据类型,这意味着变量的值不能被修改;对于对象,这意味着变量引用不能指向另一个对象,但对象内部的状态可以被修改(除非对象本身被声明为不可变)。final int MY_FINAL_VAR = 10; // 这个变量的值在初始化后不能被改变
-
最终方法:
final
方法不能被子类覆盖。它用于定义没有特殊原因不应该被改变的方法。这可以用来限制行为的扩展,或者当设计者认为方法的实现已经足够好,不应该被修改时。public final void myFinalMethod() { // 方法体 }
-
最终类: 用
final
修饰的类不能被继承。这意味着没有任何其他类可以从这个类派生。最终类可以用来表示一个类是不可扩展的,这在设计一个不会改变的框架或库时很有用。public final class MyFinalClass { // 类体 }
-
局部变量的优化(常量抓取): 在编译时,Java编译器可能会将
final
的局部变量提升到一个更大的作用域,这被称为“常量抓取”。这意味着,即使在方法内部声明了final
变量,它也可能在编译后被存储在一个类级别的区域,从而减少对栈的访问。 -
匿名内部类中的实例变量: 在匿名内部类中,如果一个实例变量被声明为
final
,它可以在匿名类中被使用,因为匿名内部类不能访问外部类的局部变量。final int outerVar = 10; new Thread(new Runnable() { public void run() { System.out.println(outerVar); // 可以访问final的外部变量 } }).start();
-
泛型中的类型参数: 在泛型中,可以使用
final
来防止类型参数被扩展或实现。public <final T> void myMethod() { // T不能是任何泛型类型的子类型 }
final
关键字是Java中一个非常重要的修饰符,它可以用来创建不可变的对象、限制继承、防止方法被覆盖以及优化编译器的内部实现。正确使用final
可以提高代码的安全性和性能,并帮助开发者表达代码的意图。
二十二、final、finally、finalize 有什么区别?
这三个关键字虽然拼写相似,但它们在Java中扮演着完全不同的角色:
-
final
关键字:final
用于声明一个不可变的实体。它可以修饰变量(成为常量)、方法(不能被重写)和类(不能被继承)。- 当变量被声明为
final
时,它必须在声明时或构造函数中初始化,且之后不能被重新赋值。 - 对于方法,
final
关键字阻止子类重写该方法。 - 对于类,
final
关键字表示该类不能有子类,即不能被继承。
public final class MyClass { private final int myFinalField = 0; // final变量 public final void myFinalMethod() {} // final方法 }
-
finally
关键字:finally
是与try-catch-finally
语句块一起使用的,用于异常处理。它指定了一段代码,这段代码在try
块和catch
块执行完毕后必定会执行,无论是否发生异常。finally
块常用于执行清理工作,如关闭文件流、释放资源等。
try { // 可能会抛出异常的代码 } catch (Exception e) { // 异常处理代码 } finally { // 一定会执行的代码,通常用于资源清理 }
-
finalize
方法:finalize
是java.lang.Object
类的一个受保护方法,它在对象被垃圾收集器回收前由JVM自动调用。finalize
方法可以被子类重写,用于在对象被回收时进行资源清理工作,如关闭文件、释放数据库连接等。- 由于垃圾收集器的调用时机不确定,以及从Java 9开始,
finalize
方法被标记为过时(deprecated),通常推荐使用try-finally
块或自动关闭资源的AutoCloseable
接口来管理资源。
public class MyClass {
protected void finalize() throws Throwable {
super.finalize();
// 清理代码
}
}
总结来说,final
关键字用于声明不可变的实体,finally
关键字用于异常处理,确保某些代码一定会执行,而 finalize
是一个方法,用于在对象被垃圾收集器回收前进行清理工作。尽管它们在语法上有相似之处,但它们的用途和行为完全不同。