final通常代表不能被改变的,使用 final的原因不外乎两个:性能与出于某种设计目的。
修饰变量
final用于修饰变量一般有如下两种
- 与static一起修饰属性成为静态常量,会分配一段固定的存储空间
- 不使用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;
}
}
修饰方法
- 防止子类覆写该方法;
- 性能。编译器把对被 final修饰的方法的调用转化为内嵌调用,不必进栈出栈。
使用final提高性能不可取,不如通过编译器和 JVM 提高性能,建议为了禁止覆写方法时才使用 final。另外private的方法没必要加final因为本身就是不可被覆写。
修饰类
一个类被 final 修饰,就意味着它不能被继承。之所以这么做,是因为类的设计就是永远不需要改动,或者是出于安全考虑不希望它有子类。例如String类。