final关键字
final可以修饰类、属性、方法、局部变量。
final的使用时机
- 不希望某个类被继承时
- 不希望某个类中属性的值被修改时
- 不希望类中的某方法被子类重写时
- 不希望局部变量的值被修改时
final修饰不同目标的具体含义
修饰目标 含义 类 不可被继承 方法 不可被重写,但可以被子类继承 属性 不可修改值 局部变量 不可修改值 方法参数 不可修改值final的注意事项
- final常量的命名通常为XX_YY
- final修饰的属性定义时必须被赋初值,初始化的位置如下
- 直接赋值
- 构造器内
- 构造代码块内
- final修饰静态属性时,初始化位置如下
- 定义时
- 静态代码块内
- final类不可被继承,但可以实例化
- final修饰的方法虽然不可被重写,但可以继承
- 如果一个类已经是final了,那它无法被继承,因此其中的方法没必要用final
- final和static搭配使用效率更高,不会导致“类加载”,因为底层编译器做了优化处理
public class Test {
public static void main(String[] args) {
System.out.println(AA.num);
}
}
class AA{
public static final int num = 10;
static {
System.out.println("AA的静态代码块被调用");
};
}
输出
10
静态代码块未被执行,说明类甚至没有被加载,编译器生成字节码文件时,编译器把对常量 num 的符号引用替换为常量值 10(即字面量)
- 包装类(Integer、Double、Float、Boolean都是fianl类型),String也是final类型,无法被继承
- final如果修饰引用类型变量,不可修改的是引用地址本身,引用对象的内部状态可变
练习题
写计算圆的面积,分别在三个地方尝试初始化PI的值
package com.hspedu.finall;
public class Test {
public static void main(String[] args) {
Circle circle = new Circle(2.0);
System.out.println(circle.calArea());
}
}
class Circle {
private double radius;
private final double PI = 3.14;
public Circle(double radius) {
this.radius = radius;
//PI = 3.14; //在构造器里赋值也可以
}
{
//PI = 3.14; 在普通代码块里赋值也可以
}
public double calArea() {
return PI * radius * radius;
}
}
PS:注意三个地方初始化都可以,但是只能保留一个,因为如果保留两个就相当于修改PI的值了
1 个帖子 - 1 位参与者