一、final简介
final意为最终的,不可变的。
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
- final修饰的类不可被继承
将一个类声明为final,其中的方法会自动地转为final(不包括变量)。
- final修饰的方法不能被重写
final修饰的方法可以重载,可以被子类继承,但是不能被重写。
使用final方法的一个原因是锁定方法,以防任何继承类修改它的含义,这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。另一个原因是效率,不过在最近的java版本(java5以后)中,已经不建议这样使用。
- final修饰的变量不能被“改变”
对于基本类型,final使数值恒定不变;而用于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的。
二、final类与不可变(immutable)类
final类一定是不可变类吗?
首先看不可变类的定义:如果类中的每个方法都不会改变其对象,这种类就是不可变的类。
也就是说,一个对象一旦被创建出来,在其整个生命周期中,它的成员变量就不能被修改了。故可知,final类不一定就是不可变类。
在Java中,所有基本类型的包装类都是不可变类,如Integer、Float等。此外,String也是不可变类。
三、一些问题
- final修饰方法参数的好处?
- 使用final修饰方法参数,参数变量不能被重新赋值,使得数据传递保持一致。
- 匿名内部类中使用它外围函数的形参或局部变量时,为什么要将其声明为final?
匿名内部类并不是直接调用方法传递的参数,而是利用自身的构造器对传入的参数进行备份,自己内部方法调用的实际上是自己的属性而不是外部方法传递进来的参数。
内部类中的属性和外部方法的参数两者表面上看是同一个东西,但实际上却不是,也就是说在内部类中对属性的改变并不会影响到外部的形参,然而从程序员的角度来看这是不可行的,毕竟从开发者的角度来说这两个根本就是同一个,如果内部类该变了,而外部方法的参数却没有改变这是难以理解和不可接受的,所以为了保持参数的一致性,就规定使用final来避免形参被改变。
因此,如果定义一个匿名内部类,并且希望它使用其外部定义的参数,那么编译器会要求该参数引用是final的。