在java中final关键字可用于修饰类,变量和方法。它用于表示它修饰的类,方法和变量不可改变。
一.简介
1.修饰变量
final修饰变量时,表示改变量一旦获得了初始值之后就不可以改变,final既可以修饰成员变量(包括类变量和实例变量),也可以修饰局部变量,形参。final修饰的变量不可被改变,一旦获得初始值后,该变量的值就不能被充值赋值。
(1)final修饰成员变量
成员变量是随类初始化或对象初始化而初始化的。当类初始化时,系统会为该类的类属型分配内存,并分配默认值;当创建对象时,系统会为该对象的实例属性分配内存,并分配默认值。因此,成员变量的初始值可以在定义该变量时指定默认值,可以在初始代码块活构造器中指定初始值,否则,成员变量的初始值将是由系统自动分配初始值。
与普通成员变量不同的是,final成员变量必须由程序员显示初始化,系统不会对final成员进行隐式初始化。
public class Test {
/*
* 1.定义该变量时指定默认值 2.初始化代码块(构造代码块或者静态代码块)或构造器中指定初始值
*/
final int a = 6;// 定义该变量时指定默认值
final int b;
final int c;
final static int d;
// final char str; 既没有指定默认值也没有在构造代码块或构造器中指定初始值,不合法
// 构造代码块,可对没有指定默认值的实例属性指定初始值
{
b = 5;// 构造代码块中指定初始值
}
// 静态代码块,可对没有指定默认值的类属性指定初始值
static {
d = 10;// 静态代码块中指定初始值
}
// 构造器,可对没有指定默认值,且没有在构造代码块中指定初始值的实例属性指定初始值。
public Test() {
c = 9;// 构造器中指定初始值
// a=9;//a已经制订默认值,不能重新为a赋值,不合法
}
public static void main(String[] args) {
new Test();
}
}
(2)final修饰局部变量
final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值,如果在定义时没有指定默认值,则可以在后面代码中队final变量赋初始值,但只能一次,不能重复赋值。
public class Test2 {
public void Testmain(final int a) {
// a=8;//非法,不能对final修饰的形参赋值
}
public static void main(String[] args) {
final int b = 10;
// b=5;//非法,定义时已指定了默认值,b变量无法重新复制
final int c;
c = 23;// 定义时没有制定默认值,则c变量可以被赋值一次
// c=35;//不合法,c变量已被赋值一次,不可被赋值
}
}
2.修饰方法
下面这段话摘自《Java编程思想》第四版第143页:
“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“
因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
public class Test3 {
public void Testmain() {
}
public static void main(String[] args) {
}
}
class Test4 extends Test3 {
public void Testmain() {
}
}
Test4 定义Testmain()方法将会出现编译错误,不能重写final方法。
public class Test3 {
private void Testmain() {
}
public static void main(String[] args) {
}
}
class Test4 extends Test3 {
private void Testmain() {
}
}
Testmain()方法是一个private方法,因为它仅在当前类中可见,子类无法访问该方法,所以子类无法重写该方法。所以子类中定义一个与父类private方法有相同的方法名,相同的形参列表,相同返回值类型的方法,是重新定义了一个新方法而不是重写。 注:类的private方法会隐式地被指定为final方法,final修饰的方法只是不能被重写,完全可以被重载
2.修饰类
当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让它被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类