final通常代表不能被改变的,使用 final的原因不外乎两个:性能与出于某种设计目的。

修饰变量

final用于修饰变量一般有如下两种

  1. 与static一起修饰属性成为静态常量,会分配一段固定的存储空间
  2. 不使用static,与类实例化相关,初始化后就不会被改变,成为常量

如果是基本类型的常量,编译器可以把常量带入计算中在 Java 中,提高一些性能。对于基本类型,final 使数值恒定不变。当用 final 修饰非基本类型对象时,final 只能保持对象引用恒定不变,例如:

final List<String> list=new ArrayList<>();
list.add("abc");
//错误:Cannot assign a value to final variable 'list'
//list=new ArrayList<>();

如果你不想在定义的时候就进行初始化赋值,那么你还有一个选择:在构造器里进行初始化。保证在使用前被final修饰的属性已经被初始化过。例如

public class Hello {
   private final int num;

   public Hello() {
      this.num = 100;
   }
}

修饰函数参数

final修饰的函数参数表示在方法中不能改变参数对象引用或基本变量,主要用于匿名内部类的数据传递。

public class Hello {
   private void hello(final int number){
      //ERROR:Cannot assign a value to final variable 'number'
      //number=100;
   }
}

修饰方法

  1. 防止子类覆写该方法;
  2. 性能。编译器把对被 final修饰的方法的调用转化为内嵌调用,不必进栈出栈。

使用final提高性能不可取,不如通过编译器和 JVM 提高性能,建议为了禁止覆写方法时才使用 final。另外private的方法没必要加final因为本身就是不可被覆写。

修饰类

一个类被 final 修饰,就意味着它不能被继承。之所以这么做,是因为类的设计就是永远不需要改动,或者是出于安全考虑不希望它有子类。例如String类。