final 关键字
应用场景
- 当不希望类被继承时,可以用
final
修饰。 - 当不希望父类的某个方法被子类覆盖 / 重写(
override
)时,可以用final
关键字修饰。 - 当不希望类的的某个属性的值被修改,可以用final修饰。
- 当不希望某个局部变量被修改,可以使用final修饰
final 的使用细节
final
修饰的属性又叫常量,一般用XX_XX_XX
命名final
修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可】:
- 定义时 — public final double TAX_RATE=0.08;
- 在构造器中
- 在代码块中
package day03;
public class Demo2 {
public static void main(String[] args) {
}
}
class AAA{
/**
* 1. 定义时赋值
* 2. 构造器中赋值
* 3. 代码块中赋值
*/
public final double TAX_RATE = 0.08; // 1. 定义时赋值
public final double TAX_RATE2;
public final double TAX_RATE3;
public AAA() { // 2. 构造器中赋值
this.TAX_RATE2 = 0.06;
}
{ // 3. 代码块中赋值
TAX_RATE3 = 0.03;
}
}
- 如果
final
修饰的属性是静态的,则初始化的位置只能是
- 定义时 — public final double TAX_RATE=0.08;
- 在静态代码块
- 不能在构造器中赋值。 原因:静态属性在类加载时就要初始化,而构造器是在创建对象时在会被调用。
class BBB{
/**
* 1. 定义时赋值
* 2. 代码块中赋值
* 3. 不能在构造器中赋值
*/
public static final double TAX_RATE = 0.08; // 1. 定义时赋值
public static final double TAX_RATE2; // 报错
public static final double TAX_RATE3;
public BBB() { // 2. 构造器中赋值 --- 报错
this.TAX_RATE2 = 0.06;
}
static { // 3. 代码块中赋值
TAX_RATE3 = 0.03;
}
}
final
类不能继承,但是可以实例化对象。- 如果类不是
final
类,但是含有final
方法,则该方法虽然不能重写,但是可以被继承。
public class Demo2 {
public static void main(String[] args) {
BB bb = new BB();
bb.cal();
}
}
class CC {
public final void cal(){
System.out.println("执行计算...");
}
}
class BB extends CC{
// 子类不能重写final修饰的方法,也不会出现 final 修饰的方法,但是会被继承,子类对象可以调用此方法。
}
- 一般来说,如果一个类已经是
final
类了,就没有必要再将方法修饰成final
方法。 final
不能修饰构造方法(即构造器)final
和static
搭配使用不会导致类加载,效率更高。底层编译器做了优化处理。【举例】
public class Demo2 {
public static void main(String[] args) {
System.out.println(CC.SCORE);
}
}
class CC {
public final static int SCORE = 100;
static {
System.out.println(" CC 静态代码块被执行...");
}
}
输出结果
9. 包装类(Integer,Double,Float,Boolean
等都是final
),String
也是final
类。