1、基本介绍
final
关键字可以修饰类、属性、方法和局部变量。
在某些情况下,我们可能有以下的需求,就会使用到final:
- 当不希望类被继承时,可以用
final
修饰; - 当不希望父类的某个方法被子类覆盖/重写(
overriide
)时,可以用final
关键字修饰; - 当不希望类的某个属性的值被修改时,可以用
final
修饰; - 当不希望某个局部变量被修改,可以用
final
修饰。
当不希望类被继承时,可以用final
修饰:
当不希望父类的某个方法被子类覆盖/重写(overriide
)时,可以用final
关键字修饰:
当不希望类的某个属性的值被修改时,可以用final
修饰:
当不希望某个局部变量被修改,可以用final
修饰:
2、final 使用时的注意事项
-
final
修饰的属性又叫常量,一般用XX_XX_XX
来命名; -
final
修饰的属性在定义时,必须赋初始值,并且以后不能再修改,赋值可以在以下位置之一【选择一个位置赋初始值即可】:
1)定义时:如public final int MAX_VALUE = 200;
2)在构造器中
3)在代码块中 -
如果
final
修饰的属性是静态的,则初始化的位置只能是:1)定义时 2)在静态代码块 ,不能在构造器中赋值; -
final
类不能被继承,但是可以实例化对象; -
如果类不是final类,但是含有
final
方法,则该方法虽然不能重写,但是该类是可以被继承的; -
一般来说,如果一个类已经是
final
类了,就没有必要再将方法修饰成final方法了; -
final
不能修饰构造器; -
final
和static
往往搭配使用,效率更高,不会导致类加载,底层编译做了优化; -
包装类(
Integer
、Double
、Float
、Boolean
等都是final
修饰的),String
也是final类;
代码演示:
public class FinalDemos01 {
public static void main(String[] args) {
AA aa = new AA();
System.out.println(aa.MAX_VALUE);
System.out.println(aa.MAX_VALUE1);
System.out.println(aa.MAX_VALUE2);
// final 类不能继承,但是可以实例化对象
CC cc = new CC();
System.out.println(BBB.NUM);
}
}
class AA {
/*
final修饰的属性在定义时,必须赋初始值,并且以后不能再修改,赋值可以在以下位置之一【选择一个位置赋初始值即可】:
1. 定义时:如 public final int MAX_VALUE = 200;
2. 在构造器中
3. 在代码块中
*/
public final int MAX_VALUE = 200;//1.定义时赋值
public final int MAX_VALUE1 ;
public final int MAX_VALUE2 ;
public AA() {//构造器中赋值
MAX_VALUE1 = 10;
}
{//在代码块赋值
MAX_VALUE2 = 800;
}
}
class BB {
/*
如果 final 修饰的属性是静态的,则初始化的位置只能是
1 定义时 2 在静态代码块 不能在构造器中赋值。
*/
public static final double TAX_RATE = 99.9;
public static final double TAX_RATE1 ;
static {
// 在静态代码块
TAX_RATE1 = 3.3;
}
// public BB() {
// // 这种方式会报错
// TAX_RATE1 = 3.3;
// }
}
//final 类不能继承,但是可以实例化对象
final class CC {
}
//如果类不是 final 类,但是含有 final 方法,则该方法虽然不能重写,但是可以被继承
//即,仍然遵守继承的机制.
class DD {
public final void cal() {
System.out.println("cal()方法");
}
}
class EE extends DD { }
//final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理
class BBB {
public final static int NUM = 10000;
static {
System.out.println("BBB 静态代码块被执行");
}
}
final class AAA {
//一般来说,如果一个类已经是 final 类了,就没有必要再将方法修饰成 final 方法
public final void cry() {
}
}