详解fianl,finally,finalize关键字

一、final

1、fianl可以修饰的内容
①修饰变量

  • 如果是基本数据类型(int,double,char)变量那么表示这个变量是不可变的,即表示一个常量,通常是大写
  • 如果是引用类型(String,Date,Animal,Person)的变量那么表示这个引用只能指向初始化时指向的那个对象,不能在执行别的对象,但这个对象的
  • fianl修饰的变量一定要有初始化的值且只能初始化一次,否则会报错(还是编译时错误)
    在这里插入图片描述

②修饰类,表示这个类是最终类,是不可被继承的。abstract与fianl是不能修饰同一个类的,因为当一个类被声明为abstract后就是要被用来继承,与fianl搭配是互相矛盾的。常见的fianl类有System,String…

③修饰方法,那么这个方法就不能被重写,但不影响子类调用父类中的fianl方法,也不影响重载。fianl与abstract不能同时修饰一个方法,原因同②

2 fianl与String的搭配,先看题目

public class Main {
    
    
   public static void main(String[] args) {
    
    
       String a = "wzh2";
       final String b = "wzh";
       String d = "wzh";
       String c = b + 2;
       String e = d + 2;
       System.out.println((a == c));
       System.out.println((a == e));
   }
}

这段代码的输出结果是什么呢?
答案是: true 和 false

1、变量a指的是字符串常量池中的 wzh2;
2、变量 b 是 final 修饰的,变量 b 的值在编译时候就已经确定了它的确定值,换句话说就是提前知道了变量 b 的内容到底是个啥,相当于一个编译期常量;
3、变量 c 是 b + 2得到的,由于 b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(wzh)来进行计算,所以 c 生成的也是一个常量,a 是常量,c 也是常量,都是 wzh2 ,而 Java 中常量池中只生成唯一的一个 wzh2 字符串,所以 a 和 c 是相等的!
4、d 是指向常量池中 wzh,但由于 d 不是 final 修饰,也就是说在使用 d 的时候不会提前知道 d 的值是什么,所以在计算 e 的时候就不一样了,e的话由于使用的是 d 的引用计算,变量d的访问却需要在运行时通过链接来进行,所以这种计算会在堆上生成wzh2 ,所以最终 e 指向的是堆上的 wzh2 , 所以 a 和 e 不相等。
总结:a、c是常量池的xiaomeng2,e是堆上的xiaomeng2

3、使用final的好处

  • final方法比非final快一些
  • final关键字提高了性能。JVM和Java应用都会缓存final变量。
  • final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
  • 使用final关键字,JVM会对方法、变量及类进行优化。

二、finally

1 用法:通常和try catch搭配使用,保证不管有没有发生异常,资源都能够被释放(释放连接、关闭IO流)
2 搭配return,不多废话,直接看题

public class Test {
    
    
    public static int test(){
    
    
        int num = 10;
        try {
    
    
            return num += 80;
        }catch (Exception e){
    
    
            System.out.println(e);
        }finally {
    
    
             if(num > 20){
    
    
                 System.out.println("num>20,num=" +num);
             }
             return num;
        }
    }
    public static void main(String[] args) {
    
    
        System.out.println(test());
    }
}

结果是:
在这里插入图片描述
原因是return num += 80被划分为了两步①num = num + 80② return num;但是在进入fianlly之前只是执行的①而没有执行②,fianlly中的num已经变成了90,执行完fianlly后再执行return,也就是再执行②

public class Test {
    
    
    public static int test(){
    
    
        int num = 10;
        try {
    
    
            return num += 80;
        }catch (Exception e){
    
    
            System.out.println(e);
        }finally {
    
    
            num += 20;
            return num;
        }
    }
    public static void main(String[] args) {
    
    
        System.out.println(test());
    }
}

返回结果是110,很简单,如果fianlly与try中都有返回值,那么try中的return会被覆盖,不再执行

三、Finalize:

Finalize是object类中的一个方法,子类可以重写finalize()方法实现对资源的回收。垃圾回收只负责回收内存,并不负责资源的回收,资源回收要由程序员完成,Java虚拟机在垃圾回收之前会先调用垃圾对象的finalize方法用于使对象释放资源(如关闭连接、关闭文件),之后才进行垃圾回收,这个方法一般不会显示的调用,在垃圾回收时垃圾回收器会主动调用。

猜你喜欢

转载自blog.csdn.net/wwwwwww31311/article/details/113174133