- final修饰符
final关键字用于修饰类,变量和方法,用于表示它修饰的类,方法和变量不可被改变。final既可以修饰成员变量也可以修饰局部变量,形参。下面我们主要探讨一下final修饰不同成分的情况。
一. final修饰成员变量
成员变量是随类初始化或者对象的初始化而初始化的。当类初始化的时候,系统会自动为类变量分配内存,并分配默认值;当创建对象时,系统为该对象的实例变量分配内存,并分配默认值。当执行静态代码块的时候会给类变量进行赋值;当执行普通代码块或者构造器的时候会给实例变量进行赋值,。因此,成员变量的初始值可以在定义该变量的时候指定默认值,也可以在初始化块,构造器中指定默认值。
对于final修饰的成员变量而言,一旦有了初始值,就不能被重新赋值,如果没有在定义成员变量,代码块,构造器中进行赋值,那么这些成员变量的值将一直是系统默认分配的 0.false,null 或者‘\u0000’,这些成员变量也失去了存在的意义了。因此java规定,final修饰的成员变量必须显示的去赋值。
归纳起来final修饰的类变量,实例变量能指定初始化的地方如下:
类变量:必须在静态代码块中指定初始值或者在声明该变量是指定初始值,而且只能在两个地方选择其中的一个。
实例变量:必须在非静态代码块中,声明该实例变量或者构造器中指定初始值,而且只能在三个地方中的其中一个指定。
//显示的在定义类变量时赋值
private final static int age = 1 ;
//在静态代码块中进行赋值
private final static int telephone ;
static {
telephone = 1;
//此做法是错误的,只能二选一
// age = 3;
}
以上是在定义类变量的时候的两种情况
//在定义实例变量是进行指定赋值
private final int money = 1;
//在定义实例变量时在非静态代码块中进行赋值
private final int aa ;
{
aa = 1;
}
//在构造器中进行赋值
private final int bb;
public FinalTest (int bb){
this.bb = bb;
}
以上是final修饰实例变量时的三种情况,当然给每一个实例变量赋值时也是只能选一个来进行赋值。
二. final修饰局部变量
系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化。因此final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。
如果final修饰的局部变量在定义时没有指定默认值时,则可以在后面的代码中对该final变量进行辅助,但是只能赋值一次,不能赋值多次,如果final修饰的局部变量已经在定义时指定了默认值,则后面的代码,就不能对该局部变量进行赋值。
public void getA ( final int a ){
//此语句非法,不能对a再次进行赋值。
// a = 2;
System.out.println(a);
}
public void showA(){
getA(3);
final int aa = 1;
//此语句非法不能再次赋值
// aa = 2;
}
上面是局部变量的一些情况,大家可以自己根据我的练习一下,当然我写的可能也会不严谨,大家可以指出我的错误。
三. final方法
final修饰的方法不能进行重写,如果出于某种原因,不希望子类重写父类的方法,则可以使用final修饰方法。
我们在看Object类中的源代码时,可以发现一个getClass()方法就是用final修饰的,因为java不希望任何类去重写这个方法,所以用final把它进行密封起来。
public class FinalMethod {
public FinalMethod(){
}
public final void set(){
System.out.println("这是一个永远不变的方法");
}
}
class ChangeTest extends FinalMethod {
//此时编译出错,不能重写父类中的方法
// public void set(){
//
// }
}
四. final类
final修饰的类不可以有子类,例如,java.lang.Math类就是一个final类,它不可以有子类,当然在java源代码中有好多的类被final修饰,有String类,System类,StringBuffer类。
public final class FinalCLassTest {
}
//只是编译出错,因为FinalClassTest是一个用final修饰的类
class FinalTest extends FinalCLassTest{
}
TIME!!!!欢迎大家来指点错误!!!