1 final 关键词的基本用法
在Java中,final关键字可用于修改类别、方法和变量(包括成员变量和局部变量)。让我们从这三个方面来了解final关键字的基本用法。
1.1 修饰类
当用final修改一个类别时,表明该类别不能被继承。换句话说,如果你永远不会让他继承一个类别,你可以用final修改它。final类中的成员变量可以根据需要设置为final,但请注意,final类中的所有成员方法都将被隐藏地指定为final方法。
使用final修饰品时,要注意慎重选择,除非以后真的不用来继承或者出于安全考虑,尽量不要把类设计成final。
1.2 修饰方法
摘自《Java编程思想》第四版第143页:
“使用final有两个原因。第一个原因是锁定方法,以防止任何继承修改其含义;第二个原因是效率。在早期的Java实现版本中,final方法将被转换为嵌入式调用。但如果方法太大,可能看不到嵌入式调用带来的任何性能改进。在最新的Java版本中,没有必要使用final方法进行这些优化。”
因此,如果你只想明确禁止, 该方法只有在子类中被覆盖时才设置为final。
注:类private方法将被隐式指定为final方法。
1.3 修饰变量
修饰变量是final使用最多的地方,也是本文下一步要重点介绍的内容。首先,了解final变量的基本语法:
对于final变量,如果是基本数据类型的变量,其值一旦初始化就不能改变;如果是引用类型的变量,则在初始化后不能指向另一个对象。
举个例子:
如图所示,两次对 arr[1] 如果使用赋值所示 final 修饰 引用类型 可以改变引用对象的变量。
2 深入理解 final 关键字2.1 final变量和普通变量有什么区别?当用 final 当作用于类成员变量时,成员变量(注意类成员变量,局部变量只需确保在使用前初始化)必须在定义或构造器中初始化,一旦初始化赋值,final变量不能再赋值。
那么final变量和普通变量有什么区别呢?以下是一个例子:
这就是final变量和普通变量的区别。当final变量是基本数据类型和string类型时,如果在编译过程中知道其确切值,编译器将将其用作编译期的常量。也就是说,在使用final变量的地方,相当于直接访问的常量,在运行过程中无需确定。
因此,在上面的代码中,由于变量b被final修改,它将被用作编译器常量,因此变量b将直接用于使用b 替换为它的 值。在运行过程中,需要通过链接访问变量d。想必大家都应该明白区别,但是需要注意的是,编译器只有在编译过程中能够准确知道final变量值的情况下才会进行这样的优化,比如下面的代码就不会优化:
2.2 被final修改的引用变量指向的对象内容可变吗?上面提到的final修改的引用变量一旦初始化赋值,就不能指向其他对象,那么引用变量指向的对象的内容可以改变吗?请参见以下示例:
public class Test { public static void main(String[] args) { final MyClass myClass = new MyClass(); System.out.println(++myClass.i); }}class MyClass { public int i = 0;}
该代码可以顺利编译并有输出结果,输出结果为1。这表明,在引用变量被final修改后,虽然不能指向其他对象,但指向对象的内容是可变的。
2.3 final 和 static很多时候,static和final关键词很容易混淆。static作用于成员变量,表示只保存一份副本,final作用是确保变量不可变。请参见以下示例:
final 变量不能修改,但是 myClass1 和 myClass2 两个对象的 i 是不同的
2.4 final参数的问题final 修饰的 引用类型变量 buffer 它不能改变,但它指向的对象可以改变
final 修饰的 基本数据类型的变量 i 不能被改变
Reference1、Java中final关键词的分析
2、Java编程思想