基本介绍
final 中文意思:最后的,最终的。
final 可以修饰类、属性、方法和局部变量。
在某些情况下会使用到final:
1) 当不希望类被继承时,可以用 final 修饰;
// 如果我们要求 A类 不能被其他类继承
// 可以使用 final 修饰 A类
final class A{}
class B extends A{} // 会报错
2) 当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰;
class C{
// 如果我们要求 hi 不能被子类重写
// 可以使用 final 修饰 hi 方法
public final void hi(){}
}
class D extends C{
@Override
public void hi() { // 会报错
System.out.println("重写了C类的hi方法...");
}
}
3) 当不希望类的的某个属性的值被修改,可以用final修饰;
public class Final01 {
public static void main(String[] args) {
E e = new E();
e.GOODS_PRICE = 75.6; // 会报错
}
}
// 当不希望类的的某个属性的值被修改,可以用final修饰
class E{
public final double GOODS_PRICE = 99.5;
}
4) 当不希望某个局部变量被修改,可以使用final修饰。
// 当不希望某个局部变量被修改,可以使用final修饰
class F{
public void TAX_RATE (){
// 这时 RATE 也称为局部变量
final double RATE = 0.09;
RATE = 0.1; // 会报错
System.out.println("RATE = " + RATE);
}
}
final使用细节
1) final修饰的属性又叫常量,一般用 XX_XX_XX来命名
2) final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【 选择一个位置赋初值即可】:
① 定义时:如 public final double GOODS_PRICE = 99.5;
② 在构造器中
③ 在代码块中
class AA{
// ① 定义时:如 public final double price = 99.5;
// ② 在构造器中
// ③ 在代码块中
public final double GOODS_PRICE = 99.5;
public final double GOODS_PRICE2;
public final double GOODS_PRICE3;
public AA(){ // 在构造器中赋值
GOODS_PRICE2 = 66.6;
}
{ // 在代码块中赋值
GOODS_PRICE3 = 77.7;
}
}
3) 如果final修饰的属性是静态的,则初始化的位置只能是:
① 定义时
② 在静态代码块,不能在构造器中赋值
class BB{
// 如果final修饰的属性是静态的,则初始化的位置只能是:
// ① 定义时
// ② 在静态代码块,不能在构造器中赋值
public static final double GOODS_PRICE = 99.5;
public static final double GOODS_PRICE2;
public static final double GOODS_PRICE3;
public BB(){ // 会报错
GOODS_PRICE2 = 66.6;
}
static { // 在静态代码块中赋值
GOODS_PRICE3 = 77.7;
}
}
4) final类不能继承,但是可以实例化对象;
5) 含有final方法,则该方法虽然不能重写,但是可以被继承;
public class Final02 {
public static void main(String[] args) {
EE ee = new EE(); // final类不能继承,但是可以实例化对象
// 含有final方法,则该方法虽然不能重写,但是可以被继承
new DD().sout();
}
}
class CC{
public final void sout(){
System.out.println("sout()方法...");
}
}
class DD extends CC{
}
final class EE{
}
6) 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法;
7) final不能修饰构造方法(即构造器);
8) final和static 往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理;
public class Final03 {
public static void main(String[] args) {
System.out.println(AAA.num);
}
}
class AAA{
public static int num = 1000;
static {
System.out.println("AAA 静态代码块被执行...");
}
}
运行结果为:
如果 num 不用 final 修饰,则运行结果为:
9) 包装类(Integer、Double、Float、Boolean等都是final),String也是final类。