目录
1.基本介绍
2.final 使用注意事项和细节讨论
3.练习题
(1)当不希望类被继承时,可以用final修饰
(2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰。【案例演示: 访问修饰符 final 返回类型 方法名】
(3)当不希望类的某个属性的值被修改,可以用final修饰。
此时这样是可以修改的。
class E{ public double TAX_RATE = 0.08; } public class Final01 { public static void main(String[] args) { E e = new E(); e.TAX_RATE=0.09; } }
那么我们要定义为不能修改。
此时想修改就会报错
(2)final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一。
class AA{
/*
1.定义时:如 public final double TAX_RATE = 0.08;
2.在构造器中
3.在代码块中
*/
public final double TAX_RATE = 0.08;
public final double TAX_RATE2;
public final double TAX_RATE3;
public AA() {
this.TAX_RATE2 =1.1;
}
{
TAX_RATE3=8.8;
}
}
(3)如果 final 修饰的属性是静态的,则初始化的位置只能是
1.定义时
2.在静态代码块 不能在构造器中
class BB{ /* 如果 final 修饰的属性是静态的,则初始化的位置只能是 1. 定义时 2. 在静态代码块 不能在构造器中赋值。 */ public static final double TAX_RATE=99.9; public static final double TAX_RATE2; public static final double TAX_RATE3; static{ TAX_RATE2=3.3; } public BB(){ TAX_RATE3=3.3; } }
构造器是在创建对象的时候才会被调用,而静态变量的初始化是在类加载的时候就要给值,这个TAX_RATE3静态变量在类加载的时候没有给值是不允许的。
(4)final 类不能继承,但是可以实例化对象
//final 类不能继承,但是可以实例化对象
final class CC{}
public static void main(String[] args) {
CC cc = new CC();
}
(5)如果类不是 final 类,但是含有 final 方法,则该方法虽然不能重写,但是可以被继承
//如果类不是 final 类,但是含有 final 方法,则该方法虽然不能重写,但是可以被继承
//即,仍然遵守继承机制
class DD{
public final void cal(){
System.out.println("cal()方法");
}
}
class EE extends DD{
}
public static void main(String[] args) {
EE ee = new EE();
ee.cal();
}
(5)一般来说,如果一个类已经是 final 类了,就没有必要再将方法修饰成 final 方法
final class AAA{ public final void cry(){ } }
我们可以看这个类,这个类用final进行修饰了,可是方法又用final进行修饰,这个地方就有点"画蛇添足",既然类已经不能被继承了,那别人也不可能去重写方法,别人都继承不了我们的类,更不可能重写里面的方法,所以我们在方法这再加一个final,没有什么意义。
(6)final不能修饰构造方法
(7)final 和 static 往往搭配使用,效率更高,不会导致类加载。底层编译器做了优化处理
这里会出现一个比较有意思的现象,我们编写一个类
//final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理 class BBB{ public static final int num = 10000; static{ System.out.println("BBB 静态代码块被执行..."); } } public static void main(String[] args) { System.out.println(BBB.num); }
声明num这个静态变量的时候,如果没有加final,那么我们去进行调用num这个静态变量的时候,类加载会导致静态代码块也会执行,但是我们加了final这个修饰符的时候,就会只执行这个静态变量,而不会因为类加载去执行静态代码块。
(8)包装类(Integer,Double ,Float,Boolean等都是final),String也是final类
public class FinalExercise01 {
public static void main(String[] args) {
Circle circle = new Circle(3.4);
System.out.println("面积="+circle.calArea());
}
}
class Circle{
private double radius;
private final double PI = 3.14;
public Circle(double radius) {
this.radius = radius;
}
public double calArea(){
return PI * radius * radius;
}
}