java学习之final

java学习之final
java学习之final

final关键字

final可以修饰类、属性、方法、局部变量。

final的使用时机

  1. 不希望某个类被继承时
  2. 不希望某个类中属性的值被修改时
  3. 不希望类中的某方法被子类重写时
  4. 不希望局部变量的值被修改时

final修饰不同目标的具体含义

修饰目标 含义 类 不可被继承 方法 不可被重写,但可以被子类继承 属性 不可修改值 局部变量 不可修改值 方法参数 不可修改值

final的注意事项

  1. final常量的命名通常为XX_YY
  2. final修饰的属性定义时必须被赋初值,初始化的位置如下
    • 直接赋值
    • 构造器内
    • 构造代码块内
  3. final修饰静态属性时,初始化位置如下
    • 定义时
    • 静态代码块内
  4. final类不可被继承,但可以实例化
  5. final修饰的方法虽然不可被重写,但可以继承
  6. 如果一个类已经是final了,那它无法被继承,因此其中的方法没必要用final
  7. 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(即字面量)

  1. 包装类(Integer、Double、Float、Boolean都是fianl类型),String也是final类型,无法被继承
  2. 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 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文