在Java中,final 关键字有三个用法,修饰变量、修饰方法以及修饰类。

修饰变量

  • final 修饰一个变量,变量的值不可以改变,这个变量也变成了一个字符常量,变量名通常要大写

    final double PI = 3.14;
    
  • final 修饰引用数据类型,那么地址值就不可以改变

    final Dog d = new Dog();
    // d = new Dog(); 地址值不可以改变
    // 对象的属性可以改变
    d.age = 10;
    
  • 注意辨别下面的两种情况

    public static void main(String[] args) {
        final Dog d = new Dog();
        a(d);
        b(d);
    }
    public static void a(Dog d){
        d = new Dog();
    }
    public static void b(final Dog d){
        //d = new Dog();
    }
    

修饰方法

如果用 final 修饰方法,那么这个方法不可以被该类的子类重写:

public class Person{
    final public void eat(){
        System.out.println("吃饭");
    }
}
public class Student extends Person{
    @override
    // public void eat(){}
}

修饰类

如果用 final 修饰类,代表没有子类,该类不可以被继承。一旦一个类被 final 修饰,那么里面的方法也没有必要用 final 修饰了(即 final 可以省略不写)。

public final class Person{
    public void eat(){
        System.out.println("吃饭");
    }
}
// public class Student extends Person{}

案例分析

这里以 Math 类为例,我们将点进它的源码进行分析。

  • 从源码中可以看到 Math 类属于 java.lang 包,所以在使用时无需导包:

    JavaSE-41-1

  • 从源码中可以看到 Math 类没有子类,不能被其他类继承:

    JavaSE-41-2

  • Math 类的属性全部被 final 修饰,方法其实也是被 final 修饰的,只是省略不写了,因为子类没有必要进行重写

  • 从源码中可以看到外界不可以为 Math 类创建对象:

    JavaSE-41-3

  • 从源码中可以看到 Math 类中的所有的属性、方法都被 static 修饰,只能通过 类名.属性名类名.方法名 去调用