Java的final修饰符

final可用于修饰类、变量和方法。
在这里插入图片描述
本文包含如下内容:

  1. final成员变量
  2. final局部变量
  3. final修饰基本类型变量和引用类
  4. 可执行“宏变量“的final变量
  5. final方法
  6. 不可变类
  7. 缓存实例的不可变类

1.final成员变量

下面程序演示了final修饰成员变量的情况
在这里插入图片描述
在这里插入图片描述
与普通成员变量不同的是,final成员变量必须由程序员显式初始化,系统不会对final成员进行隐式初始化。
如果打算在构造器、初始化块中对final成员变量进行初始化,则不要在初始化之前就访问成员变量。
如以下代码所示:
在这里插入图片描述

2. final局部变量

在这里插入图片描述
如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final 变量赋初值,但只能一次,不能重复;
下面程序示范了final 修饰局部变量、形参的情况。
在这里插入图片描述

3. final 修饰符基本类型变量和引用类型变量的区别

final修饰引用类型变量时,保存的是一个引用,final可以保证该引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。
下面程序示范了final修饰数组和Person对象的情况:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.可执行“宏替换”的final变量

final变量若满足如下三点,那么这个final变量就不再是一个变量,而是相当于一个直接量。
在这里插入图片描述
在如下程序示例中:
在这里插入图片描述
在这里插入图片描述
final 修饰符定义了“宏变量”
在这里插入图片描述
如果为final变量赋值时赋的是算术表达式或者字符串连接运算,没有访问普通方法,调用方法,java编译器同样会将这种final变量视为“宏变量”。
下面代码示例中:
在这里插入图片描述在这里插入图片描述
在上面的标为1的那行中:
在这里插入图片描述
在这里需要再次提到 Java 的常量池
在这里插入图片描述
下面是另一个 final 类型的变量:
在这里插入图片描述
在这里插入图片描述

5. final 方法

final 修饰的方法不可被重写,若不希望子类重写父类的某个方法,则可以使用final 修饰该方法。
以下说明了一种final方法的例子:
在这里插入图片描述
下面程序试图重写final 方法,将会引发编译错误。
在这里插入图片描述
但是对于private的情况有如下说明:
在这里插入图片描述
即子类可以重写 private 修饰的父类方法,以下程序示范:
在这里插入图片描述
final 修饰的方法只是不能被重写,但是可以被重载:
在这里插入图片描述

6.final 类

final 修饰的类不能有子类
例如 java.lang.Math类就是一个final 类,不可以有子类。
在这里插入图片描述

7.不可变类

不可变(immutable)类的意思是创建该类的实例后,该类的实例变量是不可改变的。
Java 提供的8个包装类和java.lang.String类都是不可变类。

例如下面的代码:
在这里插入图片描述
如果需要创建自定义的不可变类,可遵守如下规则:
在这里插入图片描述
下面程序显示了java.lang.String类的 equals()方法和 hashCode()方法。
在这里插入图片描述
下面定义一个不可变的Address类,程序把Address类的detail 和 postCode成员变量都使用 private 隐藏起来,并使用final 修饰这两个成员变量,不允许其它方法修改这两个成员变量的值。
在这里插入图片描述
在这里插入图片描述
对于上面的Address类,当程序创建了 Address 对象之后,同样无法修改Address对象的detail 和 postCode实例变量。
在这里插入图片描述
下面程序试图定义一个不可变的 Person 类,但因为 Person 类包含一个引用类型的成员变量,且这个引用类是可变类,从而导致 Person 类也变成了可变类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那么如何保护Person 对象的不可变性呢?
在这里插入图片描述
在这里插入图片描述
在上面的粗体字代码中,有如下说明:
在这里插入图片描述
因此,如果要设计一个不可变类,尤其要注意其引用类型的成员变量,如果引用类型的成员变量的类是可变的,就必须采取必要的措施来保护该成员变量所引用的对象不会被修改,这样才能创建真正的不可变类。

8. 缓存实例的不可变类

在这里插入图片描述
以下使用一个数组作为缓存池,实现一个缓存实例的不可变类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面的CacheImmutable类使用一个数组来缓存该类的对象,数组长度为MAX_SIZE,该类共可缓存MAX_SIZE个CacheImmutale对象,当缓存池已满时,缓存池采用“先进先出”规则来决定哪个对象被移出缓存池。下图示范了缓存实例的不可变类。
在这里插入图片描述
可以看出,使用CacheImmutable 类的 valueOf() 方法来生成对象时,系统是否重新生成新的对象,取决于图中被灰色覆盖的数组内是否已经存在该对象,如果该数组中已经缓存了该类的对象,系统将不会重新生成对象。

CacheImmutable 类能控制系统生成 CacheImmutable 对象的个数,需要程序使用该类的valueOf() 方法来得到其对象,而且程序使用private 修饰符隐藏该类的构造器,因此程序只能通过该类提供的valueOf() 方法来获取实例。
在这里插入图片描述
例如在Java 提供的java.lang.Integer 类中:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值