本文主要介绍了final关键字的使用方法及原理
final关键字可以修饰类,方法和引用。
修饰类,该类不能够被继承。并且这个类的对象在堆中分配内存后地址不可变。
修饰方法,方法不能被子类重写。
修饰引用,引用无法改变,对于基本类型,无法修改值,对于引用,虽然不能修改地址值,但是可以指向对象的内部进行修改。
比如:char[0]='a'. 不改变对象内存地址,只改变了值。
具体看一下下面的例子:
1 final class Fi{ 2 int a; 3 final int b=0; 4 Integer s; 5 } 6 class Si{ //一般情况下final修饰的变量一定要被初始化。 7 //只有下面这种情况例外,要求该变量必须在构造方法中被初始化。 8 //并且不能有空参数的构造方法。 9 //这样就可以让每个实例都有一个不同的变量,并且这个变量在每个实例中只会被初始化一次 10 //于是这个变量在单个实例里就是常量了。 11 final int s ; 12 Si(int s) { 13 this.s = s; 14 } 15 } 16 class Bi { 17 final int a = 1; 18 final void go() { 19 //final修饰方法无法被继承 20 } 21 } 22 class Ci extends Bi { 23 final int a = 1; 24 // void go() { 25 // //final修饰方法无法被继承 26 // } 27 } 28 final char[]a = {'a'}; 29 final int[]b = {1};
final修饰类:
1 @Test 2 public void final修饰类() { 3 //引用没有被final修饰,所以是可变的。 4 //final只修饰了Fi类型,即Fi实例化的对象在堆中内存地址是不可变的。 5 //虽然内存地址不可变,但是可以对内部的数据做改变。 6 Fi f = new Fi(); 7 f.a = 1; 8 System.out.println(f); 9 f.a = 2; 10 System.out.println(f); 11 //改变实例中的值并不改变内存地址。 12 13 Fi ff = f; 14 //让引用指向新的Fi对象,原来的f对象由新的引用ff持有。 15 //引用的指向改变也不会改变原来对象的地址 16 f = new Fi(); 17 System.out.println(f); 18 System.out.println(ff); 19 }
final修饰方法:
1 @Test 2 public void final修饰方法() { 3 Bi bi = new Bi(); 4 bi.go();//该方法无法被子类Ci重写 5 6 }
final修饰基本数据类型变量和引用:
@Test public void final修饰基本类型变量和引用() { final int a = 1; final int[] b = {1}; final int[] c = {1}; // b = c;报错 b[0] = 1; final String aa = "a"; final Fi f = new Fi(); //aa = "b";报错 // f = null;//报错 f.a = 1; }