浅谈JAVA中的final修饰符
final修饰符是JAVA中比较简单的一个修饰符,很多人通过书本就可以熟练掌握,但我学的时候,虽然感觉会用了,但是并不是十分理解这个修饰符,所以我找了相关资料,把我的个人理解分享给大家~~
final书本定义:
1.final可以修饰变量,被final修饰的变量被赋初值后,不能对它重新赋值
2.final可以修饰变量,被final修饰的方法被重写
3.final可以修饰类,被final修饰的类不能派生子类
总的来说,就是值不能改,方法不能重写,类不能继承,就相当于是终结版。。。。
一、final修饰的变量
被final修饰的实例变量必须显示地赋初值,且只能以下三种方式:
1、定义时初始化
2、在非静态初始化块中为final实例变量指定初始值
3、在构造器中指定初始值
对于局部变量,则必须赋初值,且赋值后不能再改变~
给个例子:
二、宏变量
对于一个final变量,不管它时类变量、实例变量、还是局部变量,只要定义该变量时使用了final修饰,并在定义该final类变量时指定了初始值,而且该初始值可以在编译时被确定下来,那么这个final变量实质上已经不是变量,相当于一个恒量或者是直接量。
那么,何为宏变量?顾名思义,我觉得,所谓宏变量,其实就是恒变量。当定义final变量时就为该变量指定了初始值,而且该初始值在编译时就已经确定下来,那么这个final变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方直接替换成该变量的值。
下面举一个经典例子,相信大家都遇到过:
大家先看test测试单元,这是没有添加final修饰符的,那么测试结果为 true/false。str1是一个普通字符串,str2是两个字符串直接量进行连接,由于编译器可以在编译阶段就确定s2的值”JAVAEE“,所以系统会让s2直接指向字符串池中缓存中的”JAVAEE"字符串,所以str1==str2,返回结果为true。而对于str5而言,它的值由str3和str4连接得到,但是不是由两个直接量连接,因此编译器不会执行“宏替换”,因此编译器无法在编译时确定str5的值,不会让str5指向字符串池中缓存中的“JAVAEE”,所以输出false.
大家再来看test2测试单元,只要给str3和str4添加final修饰符,将其变成宏变量,则编译器就能确定str5的值,从而输出true.
PS:对于final实例变量而言,如果要将其变为“宏变量",则必须在定义该变量时就赋初值,否则无效,下面给个例子:
三、final方法不能被重写
上面程序Base类中,用final定义父类info方法,但是被final定义的方法是不能重写的,所以exe7中的info的方法并不是重写Base中的方法,只是子类中的一个普通方法,如果要检查子类中的方法是不是重写父类中的方法,可以给方法强制添加@Override注释,如果方法报错,则不是重写方法。
四、内部类中的局部变量
注意:如果程序要在内部类中使用局部变量,那么这个局部变量必须使用final修饰!
PS:此处说的内部类指的是局部内部类,因为只有局部内部类(包括匿名内部类)才可以访问局部变量,普通静态内部类、非静态内部类不可能访问方法体重的局部变量。