【基础】final 关键字

忘是亡心i 2022-05-21 05:49 254阅读 0赞

一 final 关键字的基本用法

  1. Java 中,final 出现是源于代码设计和执行效率考虑而出现的,

final 关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。

下面就从这三个方面来了解一下 final 关键字的基本用法。

1、修饰类

  1. 当用 final 修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他

被继承,就可以用 final 进行修饰。final 类中的成员变量可以根据需要设为 final,

但是要注意 final 类中的所有成员方法都会被隐式地指定为 final 方法。

70

在使用 final 修饰类的时候,先想清楚了,除非真的出于安全考虑,以后也不想集成这个类,

否则,尽量还是别用 final 修饰一个类。

2、修饰方法

  1. 使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;

第二个原因是效率。在早期的 Java 实现版本中,会将 final 方法转为内嵌调用。

但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。

在最近的 Java 版本中,不需要使用 final 方法进行这些优化了。

3、修饰变量

  1. 对于一个 final 变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;

如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

使用 final 修饰变量的根本目的是不想让变量数据在编译或初始化之后值改变。

  1. package com.lanhuigu.java.finaldemo;
  2. import java.util.Random;
  3. /**
  4. * final 修饰变量实例:
  5. * 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
  6. * 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
  7. */
  8. public class FinalData {
  9. private static Random rand = new Random(47);
  10. private String id;
  11. public FinalData(String id) {
  12. this.id = id;
  13. }
  14. /** 编译为常量 */
  15. private final int valueOne = 9;
  16. private static final int VALUE_TWO = 99;
  17. /** 公开的常量类型 */
  18. public static final int VALUE_THREE = 39;
  19. /** 不能编译为常量 */
  20. private final int i4 = rand.nextInt(20);
  21. static final int INT_5 = rand.nextInt(20);
  22. private Value v1 = new Value(11);
  23. private final Value v2 = new Value(22);
  24. private static final Value VAL_3 = new Value(33);
  25. /** 修饰数组 */
  26. private final int[] a = {1, 2, 3, 4, 5, 6};
  27. /** 重写toString()方法 */
  28. @Override
  29. public String toString() {
  30. return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
  31. }
  32. /**
  33. * 测试调用
  34. */
  35. public static void main(String[] args) {
  36. FinalData fd1 = new FinalData("fd1");
  37. fd1.v2.i ++;
  38. fd1.v1 = new Value(9);
  39. for (int i = 0; i < fd1.a.length; i ++) {
  40. fd1.a[i]++;
  41. }
  42. System.out.println(fd1);
  43. System.out.println("Creating new FinalData");
  44. FinalData fd2 = new FinalData("fd2");
  45. System.out.println(fd1);
  46. System.out.println(fd2);
  47. }
  48. }
  49. class Value{
  50. int i;
  51. public Value(int i) {
  52. this.i = i;
  53. }
  54. }

程序结果:

fd1: i4 = 15, INT_5 = 18

Creating new FinalData

fd1: i4 = 15, INT_5 = 18

fd2: i4 = 13, INT_5 = 18

程序分析:

code1:

  1. private final int valueOne = 9;
  2. private static final int VALUE_TWO = 99;

valueOne,VALUE_TWO 均为 final 修饰原始数据,直接编译为常量,不可以修改。

code2:

  1. public static final int VALUE_THREE = 39;

VALUE_THREE 为 public 类型的常量,以供包外程序使用,static 表示这个值是唯一的,

并且在编译时候就已经初始化,而 final 表示这个值是不可以改变的,是一个常量。

code3:

  1. private final int i4 = rand.nextInt(20);
  2. static final int INT_5 = rand.nextInt(20);

定义两个随机值变量,static或non-static。从程序结果可以看出,第一次初始化FinalData对象时,

fd1: i4 = 15, INT_5 = 18

而第二次 new FinalData 对象,

fd2: i4 = 13, INT_5 = 18

从两次结果对比可以看出,i4 两次 new FinalData 的结果是不一样的,二INT_5 两次都是一样的,

这是因为 INT_5 是 static 修饰的,只初始化一次,无论 new FinalData 执行多少次,static 变量

只初始化一次,所有,第二次 new FinalData 时,INT_5 使用的值还是第一次创建时初始化的值。

而 i4 每创建一次都会重新赋值一次,所以结果不一样。

code4:

  1. private Value v1 = new Value(11);
  2. private final Value v2 = new Value(22);
  3. private static final Value VAL_3 = new Value(33);

v1 是普通引用类型变量,v2 为 final 定义,初始化之后便不能再让其指向另一个对象,

即不能再把 v2 绑定到别的新建对象上。

二 final 关键字其它常见问题

1、类的 final 变量和普通变量有什么区别?

  1. 当用 final 作用于类的成员变量时,成员变量(注意是类的成员变量,

局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,

而且 final 变量一旦被初始化赋值之后,就不能再被赋值了。

2、被 final 修饰的引用变量指向的对象内容可变吗?

在上面提到被 final修饰的引用变量一旦初始化赋值之后就不能再指向其他的对象,

那么该引用变量指向的对象的内容可变吗?

  1. package com.lanhuigu.java.finaldemo;
  2. public class ObjectContentTest {
  3. public static void main(String[] args) {
  4. final MyClass myClass = new MyClass();
  5. System.out.println(++myClass.i);
  6. }
  7. }
  8. class MyClass {
  9. int i = 0;
  10. }

程序结果:

1

程序分析:

从运行结果可以知道,final 修饰的引用变量一旦初始化赋值之后就不能再指向其他的对象,

但是,引用变量指向的对象内容是可以改变的。

3、final 修饰的方法参数不可变

一个参数被 final 修饰,这个参数值在对应的作用域内不能改变。

final修饰变量的本意就是在某些情况下,防止传进来的参数值被修改,导致不必要的错误。

网上有些文章扭曲 final 修饰参数的本意,然后写了一堆反证,其实与 final 本意

毫不相干,这种反证在 final 本意面前如小丑在一个高人面前呱呱叫。

70 1

发表评论

表情:
评论列表 (有 0 条评论,254人围观)

还没有评论,来说两句吧...

相关阅读