java基础之final

final关键字:表“无法改变”。主要谈final修饰数据,方法和类时候的作用。

1.final数据

  ①一个永不改变的编译时常量:final修饰的基本数据类型,必须对其进行赋值(空白final后面讲)

//can be compile-time constants
private final int valueOne = 9;
private static final int VALUE_TWO = 99;//既是static又是final的域只占据一段不能改变的存储空间。带有恒定初始值的final static修饰的基本类型用全大写命名,中间用_隔开


//typical public constants
public static final int VALUE_THREE = 39;

  ②运行时被初始化的值,你不希望它被改变:

//can be compile-time constants
private final int i4 = rand.nextInt(20);
static final int INT_5 = rand.nextInt(20);//装载时已初始化,而不是每次新建一个对象都初始化,所以该值不会变化

  当对对象引用(包括数组的使用)。而不是基本数据类型使用final时,表示引用不变,初始化将其指向一个对象,就无法把它改为指向另一个对象,但是对象自身不受限定,可被修改。

空白final:声明为final有没给定初值的域。无论在哪种情况下,空白final都必须在实际使用前得到正确的初始化(Blank finals MUST be initialized in the constructor:)。而且,编译器会主动保证这一规定得以贯彻。

然而,对于final 关键字的各种应用,空白final 具有最大的灵活性。

举个例子来说,位于类内部的一个final 字段现在对每个对象都可以有所不同,同时依然保持其“不变”的本质

final参数: 无法在方法中更改参数引用所指向的对象

public class blackfinal {
        private final int i = 0;    //initialized final
        private final int j;        //blank final
        private final Poppet p;     //blank final reference

     public blackfinal() { j = 1; p = new Poppet(); } public blackfinal(int j) { this.j = j; p = new Poppet(j); } int g(final int i){ //final参数 return i+1; } public static void main(String[] args) { blackfinal bf = new blackfinal(); System.out.println("bf: i="+bf.i+" j="+bf.j); //bf: i=0 j=1
            blackfinal bf2 = new blackfinal(47);                       
            System.out.println("bf: i="+bf2.i+"   j="+bf2.j);          //bf: i=0 j=47
         int x= 3;
System.out.println(
"bf.g(x) = "+bf.g(x)+" | x = "+x); //bf.g(x) = 4 | x = 3
      } 
  }

  class Poppet {
    
private int i;
     Poppet(
int ii){ i = ii;}
 
public Poppet() { }
}

 2.final方法

   ①把方法锁定,以防任何继承类来修改它,确保在继承中使方法保持不变,防止被覆盖

   ②效率考虑(基本不用了,效率问题交给编译器和JVM去处理):对一个final方法进行调用时,跳过插入代码这种正常的方式而执行方法调用机制(将参数入栈,跳至方法代码处执行,再调回并清理栈中参数,处理返回值),并以方法体中实际代码的副本代替方法调用,消除方法调用开销。

   类中所有private方法都隐式指定为final。(private无法被获取,所以无法被重写覆盖,子类中就算写了相同方法名的方法,也仅仅只是方法名相同的新方法而已,并没有产生覆盖)

 3.final类

   ①final类不允许被继承(类的设计无须再改动/处于安全的考虑,不希望有子类),故final类中所有方法都隐式制定为final :final class A{...}

       Java中有许多类是final的,譬如String, Interger以及其他包装类。

final关键字的好处

下面总结了一些使用final关键字的好处

  1. final关键字提高了性能。JVM和Java应用都会缓存final变量。
  2. final变量可以安全的在多线程环境下进行共享(不可变,即只读),而不需要额外的同步开销。
  3. 使用final关键字,JVM会对方法、变量及类进行优化。

关于final的重要知识点

  1. final关键字可以用于成员变量、本地变量、方法以及类。
  2. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
  3. 你不能够对final变量再次赋值。
  4. 本地变量必须在声明时赋值。
  5. 在匿名类中所有变量都必须是final变量。
  6. final方法不能被重写。
  7. final类不能被继承。
  8. final关键字不同于finally关键字,后者用于异常处理。
  9. final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。
  10. 接口中声明的所有变量本身是final的。
  11. final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
  12. final方法在编译阶段绑定,称为静态绑定(static binding)。
  13. 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。
  14. 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
  15. 按照Java代码惯例,final变量就是常量,而且通常常量名要大写
原文地址:https://www.cnblogs.com/Janine-S/p/8666055.html