Java关键字 - final

概念

在Java中,我们可以通过final来表示某个变量、某个方法,甚至是某个类是“不变的”或“无法改变的”。

怎么使用final

final变量

final修饰的变量称之为常量,其主要应用于以下地方:

  • 编译器常量,永远不可改变。
  • 运行其初始化时,我们希望它不会被改变。

对于编译器常量,它在类加载的过程就已经完成了初始化,所以当类加载完成后是不可改变的。而对于运行时变量,也称为空白final,即代表先声明,后赋值这一过程。

运行时变量可分为基本数据类型与引用数据类型,其中基本数据类型不可变的是内容,而引用数据类型的不可变的是引用,引用所指的对象内容是可变的。

1
2
3
4
5
6
7
8
9
10
11
public class Test {
private final int SIZE;
private final String test = "final can't change";

public Test(int size) {
// 运行期变量,可以根据传递的值来声明不同的常量
this.SIZE = size;
// 编译器报错,因为test被final修饰,其在编译期间已确定的值,所以不可改变
this.test = "final??";
}
}

final方法

final修饰的方法都是不能被继承、更改的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Father {
public final void hello() {
System.out.println("father can't change");
}

public static void main(String[] args) {
new Son().hello();
}
}

class Son extends Father {
// 编译器报错,因为Father类中的hello()被final修饰,所以子类是不能够重写的
public void hello() {
System.out.println("hhello");
}
}

final参数

final修饰的参数都是不可变的,即在函数作用域内,该参数的值都是不可变的。

1
2
3
4
5
public void hello(final String str) {
// 编译出错
str = "world";
System.out.println(str);
}

final类

final修饰的类是不允许被继承的,所以可视该类为最终类。

1
2
3
4
5
6
7
8
public final class Father {

}

// 编译出错,Father类不可被继承
class Son extends Father {

}

final能提高性能吗?

基于JVM对于声明为final的局部变量(local var)做了哪些性能优化?在Java中使用final关键字会提高性能吗?两文,可以归纳总结出final关键字并不会从性能上有很大的提升,甚至可以说是没有。反而要求设计者在程序设计中,不要过分追求性能,需要注重的是代码的可读性与可维护性。


参考资料

java提高篇(十五)—–关键字final