final修饰符具有“不可改变”的含义,它可以修饰类、成员方法和变量:
- 用final修饰的类不允许被继承,即没有子类。
- 用final修饰的成员方法不允许被子类的方法覆盖。
- 用final修饰的变量表示常量,只允许被赋一次值。
一锤定音的final修饰符
1. final类
用final修饰的类不允许有子类。在以下情况,可以考虑把类定义final类型,使得这个类不能被继承:
- 不是专门为继承而设计的类,类的方法之间有复杂的调用关系。假如随意创建这些类的子类,子类有可能会覆盖父类的方法,并且错误地修改父类的实现细节。
- 出于安全的原因,类的实现细节不允许有任何改动。
- 确信这个类不会再被扩展。
例如JDK类库中的java.lang.String类定义为final类型:
public final class String{……}
以下MyString类试图继承String类,这会导致编译错误:
//非法,不允许创建String类的子类
public class MyString extends String{……}
2. final方法
在某些情况下,出于安全的原因,父类不允许子类覆盖某个方法,此时可以把这个方法声明为final类型。例如在java.lang.Object类中,getClass()方法为final类型:
//返回包含类的类型信息的Class实例
public final Class getClass(){……}
Object类的子类不能覆盖getClass()方法。以下Cat类试图覆盖Object类的getClass()方法,这会导致编译错误:
public class Cat{
String name;
public Cat(String name){this.name=name;}
//非法,不允许覆盖Object类的getClass()方法
public Class getClass(){
//返回包含Dog类的类型信息的Class实例
return Class.forName("Dog");
}
}
3. final变量
在现实世界中,有些变量的取值是固定不变的常量,例如圆周率(π)、标准大气压、国内的民用标准电压等。
在Java语言中,用final修饰的变量就表示取值不会改变的常量:
final int STANDARD_VOLTAGE=220 ; //标准民用电压
再例如在java.lang.Integer类中定义了两个常量:
//表示int类型的最大值
public static final int MAX_VALUE= 2147483647;
//表示int类型的最小值
public static final int MIN_VALUE= -2147483648;
final变量只能赋值一次,以下代码的第二行语句试图修改final类型的变量a的值,这是非法的:
final int a=1;
a=2; //非法,不能修改a的值
类的成员变量可以不必显式初始化,但是这不适用于final类型的成员变量。final变量都必须显式初始化,否则会导致编译错误:
public class Sample{
final int var1; //非法,var1必须被显式初始化
final static int var2; //非法,var2必须被显式初始化
final int var3=0; //合法,声明时显式初始化
final static int var4=0; //合法,声明时显式初始化
final int var5;
final static int var6;
static{
var6=0; //合法,在静态代码块中显式初始化
}
public Sample(){
var5=0; //合法,在构造方法中显式初始化
}
}
final类型的实例变量var3在声明时显式初始化,final类型的实例变量var5在构造方法中显式初始化,final类型的静态变量var4在声明时显式初始化,final类型的静态变量var6在静态代码块中显式初始化。
上文参考孙卫琴的经典Java书籍《Java面向对象编程》