final关键字你真的会了吗

593 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

什么是final

final是java中的一个关键字,可以修饰变量(成员变量+局部变量)、方法以及类。

final常量

final修饰常量有以下特点:

如果引用为基本数据类型,则该引用为常量,该值无法修改;

如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。

如果引用时类的成员变量,则必须当场赋值,否则编译会报错:定义时赋值或构造函数内赋值

final修饰常量基本类型和引用类型有些不同。

基本数据类型:

 private final int A;
 private final int B = 3;
 private final int C = new Random().nextInt();
 public Test() {
 this.A = 5;
 }
 public Test(int a) {
 this.A = a;
 }
}

像B这种确定值(定义便立即赋值)的final常量,编译器会在编译时将该常量值带入到任何可能用到它的计算式中,这会减轻运行时的一些负担。

引用类型:

引用类型不能改变指的是引用被初始化指向一个对象后,就再也无法改为指向其他对象,但其指向的对象本身是可以被修改的。

 //final常量d指向了对象D
 private final D d =new D();
 //这个方法改变了对象D的内容
 public D change(){
 this.d.setS("change");
 return d;
 }
 //注意这个方法,将常量d的引用改变了
 public D refnewD(){
 this.d = new D();
 return d;
 }
 class D {
 private String s= "init";
 public String getS() {
 return s;
 }
 public void setS(String s) {
 this.s = s;
 }
 }
}

上面代码是无法编译的,因为this.d=new D()会提示Cannot assign a value to final variable 'd',但是你却可以调用change()方法来改变d对象的s变量值。

final修饰方法

final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。相当于把方法锁定,防止继承类修改它的含义。

class A 
{
    final void m1() 
    {
        System.out.println("This is a final method.");
    }
}

class B extends A 
{
    void m1()
    { 
        // COMPILE-ERROR! Can't override.
        System.out.println("Illegal");
    }
}

需要注意的是:当一个方法被private修饰,这会隐式的指定为final,这也会使得子类无法覆盖此方法,可以对private方法增加final修饰。

final修饰类

final修改类时,该类成为最终类,无法被继承。一旦类被final修饰,即代表final类中的所有成员变量和方法都会隐式的final。

public final class FinalDemo {
    public int a;
}
public class InheritFinalDemo Extends FinalDemo{
    public int b;
}

会遇到如下提示:

Cannot inherit from final class

final相关

static 和 final

1、static强调的是该数据只存在一份,且是属于类的,不是属于对象。

2、final强调该数据不可变,且是属于对象的。

 private final double A = 3.14D;
 private static double b = 3.14D;
 public static void main(String[] args) {
 new C();
 new C();
 new C();
 }
}

面代码运行后,A会存在3个,但b只有一个。

final,finally和finalize

finally是在异常处理时配合try-catch执行清理操作,需要清理的资源包括:打开的文件或网络连接等,它会把内存之外的资源恢复到他们的初始状态。无论try中是否有异常出现,finally里的操作都会被执行。 finalize这是Object基类的一个方法,垃圾收集器在将对象清除出内存之前调用的清理资源方法,且此方法只会被系统调用一次,其实finalize能做的工作,try-finally能做的更好。

总结

final关键字主要用在三个地方:变量、方法、类。

如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。

final修饰方法时会把方法锁定,以防任何继承类修改它的含义。