Java面试 - final、finally、finalize的区别?

final:用于声明属性, 方法和类,分别表示属性不可变、方法不可覆盖、被其修饰的类不可继承。

finally:异常处理语句结构的一部分,表示总是执行。

finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的finalize()方法。JVM不保证此方法总被调用。

举例:

修改被final修饰的属性nickName

public class Student{
 public static void main(String[] args) {
   final String nickName ="Jack";
   nickName = "Jack Ma";
 }
}

运行结果

Error:(27, 5) java: 无法为最终变量nickName分配值

由此说明被final 修饰的属性是不可变的。
那么,final 修饰的方法setName()是否可以被重写呢?

class Person {
  private String name;
  public final void setName(String name){
      this.name = name;
  }
}
public class Student extends Person{
  // 重写被final 修饰的setName()方法
  public void setName(String name){
    System.out.println(name);
  }
}

运行结果

Error:(27, 15) java: Student中的setName(java.lang.String)无法覆盖
Person中的setName(java.lang.String),被覆盖的方法为final

由此说明被final 修饰的方法是不能被重写的。
那么,final修饰的类是否可以被继承呢?

final class Person {
  private String name;
  public void setName(String name){
      this.name = name;
  }
}
// 继承被final 修饰的Person类
public class Student extends Person{
}

运行结果

Error:(24, 30) java: 无法从最终Person进行继承。

由此说明被final 修饰的类是不能被继承的。
当没有出现异常时,异常处理语句中的finally 是否会被执行呢?

public class Student {
  public static void main(String[] args) {
    try {
      int i = 1;
      int result = i / 1;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.print(""没有出现异常时,执行finally"");
    }
  }
}

运行结果

没有出现异常时,执行finally

当出现异常时,异常处理语句中的finally 是否会被执行呢?

public class Student {
  public static void main(String[] args) {
    try {
      int i = 1;
      int result = i / 0;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.print(""出现异常时,执行finally"");
    }
  }
}

运行结果

java.lang.ArithmeticException: / by zero
	at Student.main(Student.java:27)
出现异常时,执行finally

由此可知,异常处理语句结构的一部分finally{},无论是否出现异常,finally{}一定会被执行。
最后我们再来看一下,finalize()方法是如何使用的?


class Person {
  private String name;
  public void setName(String name){
    this.name = name;
  }
  public String getName(){
    return name;
  }
  @Override
  protected void finalize() throws Throwable {
    System.out.print("调用finalize()方法,在Student对象从内存中删除之前对setName进行清理操作");
    super.finalize();
  }
}
public class Student extends Person {
  public static void main(String[] args) throws Throwable {
    Student s1 = new Student();
    Student s2 = new Student();
    System.out.println("s2=s1之前,s1指向的对象地址:"+s1);
    System.out.println("s2=s1之前,s2指向的对象地址:"+s2);
    // 设置name
    s1.setName("Rose");
    s2.setName("Jack");
    //将s1指向的对象地址赋给s2, 则s1和s2指向的是同一个对象地址
    s2=s1;
    System.out.println("s2=s1之后,s1指向的对象地址:"+s1);
    System.out.println("s2=s1之后,s2指向的对象地址:"+s2);
    // 显式调用垃圾回收方法 触发finalize()
    System.gc();
    System.out.println("学生名字:"+s1.getName());
  }
}

运行结果

s2=s1之前,s1指向的对象地址:Student@a09ee92
s2=s1之前,s2指向的对象地址:Student@30f39991
s2=s1之后,s1指向的对象地址:Student@a09ee92
s2=s1之后,s2指向的对象地址:Student@a09ee92
学生名字:Rose
调用finalize()方法,在Student对象从内存中删除之前对setName进行清理操作。
Process finished with exit code 0

从运行结果来看,在垃圾回收器执行的时候会调用被回收对象的finalize()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值