final
作用
final:最后的 最终的
final可以修饰 类 方法 属性 和局部变量
- 当final修饰一个类时,这个类就不能被继承
public class final1 {
}
final class A{}
class B extends A{}//会报错
- 放final修饰一个方法时,此方法就不能被子类重写override
class A{
public final void print1(){
System.out.println("嘀嘀嘀");
}
}
class B extends A{
public void print1(){}//报错
}
- 当final修饰类的属性时,此属性就成为一个常量。无法被修改
public class final1 {
final int NUM = 12;
NUM = 12;//报错
}
4.当final修饰局部变量时,此局部变量就成为了局部常量,也无法被修改
final使用注意事项
- final修饰的属性叫做:常量 命名规范为 XX_XX_XX.单词全大写,后面还有其他单词使用下划线隔开
- final修饰的属性在定义时,必须赋值,并且以后不能更改,非静态常量可以在:1.定义时 2.构造器 3.普通代码块中随便一个地方放赋值。
- 如果是静态常量,只能在:1.定义时 2.静态代码块 两个地方赋值
- final修饰的类虽然不能被继承,但是依旧可以实例化
- 如果普通类中有final修饰的方法,虽然此方法不能被子类重写,但是该类还是可以被继承
- 如果一个类是final修饰,那么就没必要将方法修饰成final方法了。因为都无法被继承了,自然不可能被重写
- final不能修饰构造器方法
- final和static搭配使用,效率更高,可以避免类加载。是对底层编译器进行了一种优化处理
第二点非静态和静态属性常量初始化演示:
非静态常量初始化
public class final1 {
//非静态常量初始化
//1.直接定义初始化 final int NUM = 1;
final int NUM ;
//2.在普通代码块初始化
{
NUM = 1;
}
//3.在构造器初始化
public final1(int NUM) {
// this.NUM = NUM;
}
}
静态常量初始化
public class final1 {
//静态常量初始化
//1.直接定义初始化 final int NUM = 1;
final static int NUM ;
//2.在静态代码块初始化
static {
NUM = 1;
}
}
第八点代码演示:
当在main方法中使用静态属性 类名.静态属性名。这样会导致类加载,而在有些时候,我们不希望类加载,只是单纯的使用一下这个属性。此时就可以使用final和static搭配修饰这个属性
public class final1 {
public static void main(String[] args) {
System.out.println(AA.NUM);
}
}
class AA{
public final static int NUM = 12;
static {
System.out.println("静态代码块被调用");
}
}
运行结果:
12
可以看到并没有输出 静态代码块被调用 。这也说明AA类并没有被加载
final练习
- 编写一个程序,能够计算圆的面积。圆周率使用3.14。将常量赋值的3个位置都写一下
public class final1 {
public static void main(String[] args) {
Circle circle = new Circle(6);
System.out.println(circle.carArea(6));
}
}
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 carArea(double radius){
return radius*radius*PI;
}
}
- 看下面代码有没有错误,为什么?
public class BB{
public int addOne(final int x){
++x;//错误,不可以修改常量的值
return x+1;//正确,返回的是一个新的值,没有修改常量
}
}