一. final 数据
对于final修饰的数据,有以下两种情况:
1. 一个永不改变的编译常量
1: public class FinalTest{
2: private final static int VALUE = 1;
3: }
对于编译常量,编译器可以在编译期常量的值,减轻运行时的负担。其中,static强调只有一份,而final强调它是一个常量。在Java中,这类常量必须是基本数据类型,并且在对这个常量进行定义的时候,必须对其赋值。
2. 一个在运行时被初始化的值,而你不希望它被改变
(1)final修饰基本数据类型
1: public class FinalTest{
2: private final int value = 1;
3: public void test(int n){
4: value = n; //The final local variable s cannot be assigned. It must be blank and not using a compound assignment
5: }
6: }
对于final修饰的基本数据类型,final使其数据保持恒定不变,如上所示,value的值只能为1,不能被修改。
(2) final修饰引用类型
1: public class FinalTest{
2: private final TreeNode root = new TreeNode(1);
3: public void test(){
4: root = new TreeNode(2) //error
5: root.val = 2; //OK
6: }
7: }
8: class TreeNode{
9: private int val;
10: TreeNode left;
11: TreeNode right;
12: TreeNode(int val){
13: this.val = val;
14: }
15: }
final保证引用对象的地址恒定不变,即无法把他指向另一个对象,但是final修饰对象的本身是可以改变。
二 final 参数
java允许在参数列表中以声明的方式将参数指明为final,表示在方法内部你无法更改参数所引用的对象。
1: public class FinalTest{
2: public void test1(final TreeNode root){
3: root = new TreeNode(2) //error
4: }
5:
6: public void test2(TreeNode root){
7: root = new TreeNode(2) //OK
8: }
9: }
10: class TreeNode{
11: private int val;
12: TreeNode left;
13: TreeNode right;
14: TreeNode(int val){
15: this.val = val;
16: }
17: }
这一特性主要用于向匿名内部类传递参数
如果你定义了一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求参数引用参数是final的。
1: public class FinalTest{
2: public Class1 test1(final String str){
3: return new Class1(){
4: private String label = str;
5: }
6: }
7:
8: public Class2 test2(String str){
9: return new Class2(){
10: public void f(){
11: System.out.println("anonymous");
12: }
13: }
14: }
15:
16: }
对于匿名内部类Class1,因为其需要引用外部的对象str,所以需要将引用的参数用final,而对于匿名内部类Class2,它不需要引用外部的变量,所以不需要用fina修饰。
三. 空白final
空白final是指被声明为final但又未给定初值的域。无论什么情况,编译都要确保空白final在使用前都要被初始化。
1: public class FinalTest{
2: private final int i = 0; //Initialized final
3: private final int j; // Blank final
4:
5: public FinalTest(){
6: j = 1; // 初始化空白final
7: }
8:
9: public FinalTest(int x){
10: j = x; // 初始化空白final
11: }
12: }
四 final的总结
1. final类不能被继承,也就是其没有子类,final中的方法默认为final方法
2. final方法不能被子类的方法覆盖,但是可以被继承
3. final不能用来修饰构造函数