小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
什么是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修饰方法时会把方法锁定,以防任何继承类修改它的含义。