1

本文主要介绍了final关键字的基本使用方法及原理

final关键字可以修饰类、方法和引用。

修饰类,该类不能被继承。并且这个类的对象在堆中分配内存后地址不可变。

修饰方法,方法不能被子类重写。

修饰引用,引用无法改变,对于基本类型,无法修改值,对于引用,虽然不能修改地址值,但是可以对指向对象的内部进行修改。

比如char[0] = 'a'。不改变对象内存地址,只改变了值。

具体看一下下面的栗子:

  1. final class Fi {
  2. int a;
  3. final int b = 0;
  4. Integer s;
  5. }
  6. class Si{
  7. //一般情况下final修饰的变量一定要被初始化。
  8. //只有下面这种情况例外,要求该变量必须在构造方法中被初始化。
  9. //并且不能有空参数的构造方法。
  10. //这样就可以让每个实例都有一个不同的变量,并且这个变量在每个实例中只会被初始化一次
  11. //于是这个变量在单个实例里就是常量了。
  12. final int s ;
  13. Si(int s) {
  14. this.s = s;
  15. }
  16. }
  17. class Bi {
  18. final int a = 1;
  19. final void go() {
  20. //final修饰方法无法被继承
  21. }
  22. }
  23. class Ci extends Bi {
  24. final int a = 1;
  25. //        void go() {
  26. //            //final修饰方法无法被继承
  27. //        }
  28. }
  29. final char[]a = {'a'};
  30. 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. Fi ff = f;
  13. //让引用指向新的Fi对象,原来的f对象由新的引用ff持有。
  14. //引用的指向改变也不会改变原来对象的地址
  15. f = new Fi();
  16. System.out.println(f);
  17. System.out.println(ff);
  18. }

final修饰方法

  1. @Test
  2. public void final修饰方法() {
  3. Bi bi = new Bi();
  4. bi.go();//该方法无法被子类Ci重写
  5. }

final修饰基本数据类型变量和引用

<pre>

  1. @Test
  2. public void final修饰基本类型变量和引用() {
  3. final int a = 1;
  4. final int[] b = {1};
  5. final int[] c = {1};
  6. //  b = c;报错
  7. b[0] = 1;
  8. final String aa = "a";
  9. final Fi f = new Fi();
  10. //aa = "b";报错
  11. // f = null;//报错
  12. f.a = 1;
  13. }


程序员黄小斜
947 声望123 粉丝