对于final修饰符的基本认识是:方法不可以被子类重写、变量值不可重新赋值、类不可派生出子类。
对于普通变量,java程序可以为它执行默认值,但对于Final修饰的变量必须显示地赋值。
此外对于final修饰符,需要比较关注的有以下内容。
(1)定义的变量成为“宏变量”
即如果一个被final修饰的变量在定义时就赋了初值,它的值在编译时就确定了下来,相当于宏定义。
看一个例子。
class Price{
//类成员是Price实例
final static Price INSTANCE = new Price(2.8);
//final static double initPrice = 20;
static double initPrice =20; ①
//定义该Price的currentPrice的实例变量
double currentPrice;
public Price(double discount){
//根据静态变量计算实例变量
currentPrice = initPrice-discount;
}
}
public class PriceTest{
public static void main(String args[]){
Price p= new Price(2.8);
System.out.println(p.currentPrice);//输出了17.2
System.out.println(Price.INSTANCE.currentPrice); //② 输出的是什么?为什么?
}
}
为什么语句②输出的是-2.8?不明白的话回忆一下类的初始化过程。final static Price INSTANCE = new Price(2.8);时,initPrice变量的值为0,它是默认的初始值;
如果把语句①换为其上一句(标了黄色),那么,语句②输出的就是17.2了。也就是执行final static Price INSTANCE = new Price(2.8);时允许“向下引用”了initPrice = 20。
(2)内部类中使用局部变量
如果程序需要在内部类中使用局部变量,那么这个局部变量必须使用final修饰符修饰。
为什么?
再看一例子:
public class FinalClosure{
public static void main(String args[]){
final String str ="Iris"; ①
//定义一个线程
new Thread(new Runnable(){
public void run(){
System.out.println("看!带着"+str+"到其他地方去了
!");
}
}).start();
System.out.println("main()到此结束,但"+str+"去其他地方了。可是,因为有
final修饰,"+str+"就不会变了。这就是JAVA设计时为防止变量在使用过程中产生混乱而做的约
定...");
}
}
运行结果:
如果语句①中没有final修饰,那么在线程中,很有可能使得局部变量str的值被改变,产生逻辑上的错误,而众所周知这种错误是比较难发现的。所以java中内部类使用局部变量时,局部变量必须用final修饰。
PS:部分代码摘自《疯狂java》