文章目录
- 1. final
- 2. finally
- 3. finalize
1. final
"final"是Java中的一个关键字,用于表示不可更改或不可继承的实体。它可以应用于变量、方法和类。
- final 变量 在Java中,如果一个变量被声明为“final”,则它将被视为常量,其值不能被修改。这意味着一旦初始化,该变量的值就不能再次更改。通常,final变量被视为常量,并且必须在声明时初始化。例如:
Copy Codefinal int MAX_VALUE = 100;
- final 方法 如果一个方法被声明为“final”,则子类将无法覆盖该方法。这意味着在子类中无法重写该方法以实现其自己的行为。例如:
Copy Codepublic class Animal {
public final void move() {
System.out.println("Animals can move");
}
}
public class Dog extends Animal {
public void move() { // 编译错误,无法重写 final 方法
System.out.println("Dogs can walk and run");
}
}
- final 类 如果一个类被声明为“final”,则该类不能被继承。这意味着不能创建该类的任何子类。例如:
final class Parent {
// code
}
class Child extends Parent { // 编译错误,无法继承 final 类
// code
}
使用final关键字将变量、方法或类标记为不可更改或不可继承,有助于确保代码的安全性和稳定性。
2. finally
"finally"是Java中的一个关键字,用于定义在try-catch块之后执行的代码块。即使在try-catch块中引发了异常,finally代码块也将始终执行,以便释放资源或完成其他清理操作。它通常与try和catch一起使用。
以下是finally使用的示例:
try{
// 可能会引发异常的代码
}
catch(Exception e) {
// 异常处理代码
}
finally {
// 始终执行的代码
}
在上述代码中,try块包含可能会引发异常的代码,catch块包含捕获异常并执行适当的处理代码的语句。无论try块中是否有异常,finally块中的代码都将被执行。这有助于确保在任何情况下都可以执行必要的清理操作,例如关闭文件、数据库连接或网络资源等。
在 Java 中,
finally
块中的代码总是会被执行,无论是否发生了异常,并且不管有没有return
语句。这也是finally
关键字的主要作用之一,用于确保在程序执行过程中必须完成的操作能够得到正确地执行,例如关闭文件或网络连接等操作。值得注意的是,在
try-catch-finally
语句中,如果在try
或catch
块中出现了return
语句,那么该return
语句所携带的返回值将会被暂存起来,在fxianinally
块中的代码执行完毕后再进行返回。而且,如果在finally
块中也出现了return
语句,那么它将覆盖之前的返回值,成为最终的返回结果。
在总体结构中,try块、catch块和finally块可以按照以下顺序组合使用:
try{
// 可能会引发异常的代码
}
catch(ExceptionType1 e1) {
// 处理 ExceptionType1 异常
}
catch(ExceptionType2 e2) {
// 处理 ExceptionType2 异常
}
...
finally {
// 始终执行的代码
}
总之,finally关键字用于定义始终执行的代码块,以确保必要的清理操作可以在任何情况下都会被执行。
3. finalize
在Java中,finalize()
方法是一个特殊的方法,它被用来在对象被垃圾回收之前进行一些清理操作。当一个对象变成垃圾对象时,JVM会自动调用该对象的finalize()
方法,来释放一些资源或执行必要的清理操作。
需要注意以下几点:
-
finalize()
方法是protected类型的方法:这意味着我们只能在同一个包或者子类中使用它。在其他地方,我们无法主动调用该方法。 -
finalize()
方法最好不要依赖它:因为垃圾回收器并不能保证什么时候会调用finalize()
方法,所以不能够将其视为一种可靠的资源管理方式。更好的方式是在程序中手动维护资源,并且及时释放和关闭它们。 -
finalize()
方法会影响垃圾回收的效率:因为Java的垃圾回收机制非常复杂,所以在执行finalize()
方法时会占用垃圾回收器更多的时间和内存。如果有太多的对象都实现了finalize()
方法,那么可能会导致垃圾回收效率下降,从而影响程序的性能。 - 多个对象共享某些资源时,
finalize()
方法会出现问题:例如,多个Java对象共享同一个文件描述符时,如果其中一个对象的finalize()
方法关闭了该文件描述符,那么其他共享该文件描述符的对象就无法再使用该文件描述符了。
综上所述,虽然finalize()
方法可以用于释放资源、关闭文件等操作,但是它并不是一种可靠的资源管理方式。在实际开发中,最好手动维护资源,并且及时释放和关闭它们,以免出现意外问题。
如果,在执行完finalize()
方法之后,如果该对象重新被引用,那么它就会“复活”。
具体来说,当一个对象变成垃圾对象时,JVM会调用该对象的finalize()
方法进行清理操作。如果在finalize()
方法执行期间,该对象被重新引用了,那么这个对象就不再是垃圾对象了,即它被“复活”了。例如:
public class Example {
private static Example instance;
public void finalize() {
System.out.println("Object is being finalized");
instance = this;
}
public static void main(String[] args) {
Example obj1 = new Example();
obj1 = null;
//触发GC
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (instance != null) {
System.out.println("Object is not null");
} else {
System.out.println("Object is null");
}
}
}
在该例子中,Example
类实现了finalize()
方法,并且在该方法中将instance
变量设置为当前对象。然后,我们创建了一个Example
对象,将其赋值为null
,并强制执行垃圾回收。在等待一段时间后,我们检查instance
变量是否为空。
由于finalize()
方法将instance
变量设置为当前对象,所以在垃圾回收器执行finalize()
方法时,该对象被复活了。因此,在等待一段时间后,instance
变量不为空,输出为“Object is not null”。
需要注意的是,即使对象被复活了,它也不会完全恢复到之前的状态,因为它的所有成员都已经失效。因此,在实际开发中,我们应该尽量避免使用finalize()
方法来进行资源管理和清理操作,以免出现意外问题。