⭐️小剧场⭐️
👻:下面有关java final的基本规则,描述错误的是?
A. final修饰的类不能被继承
B.final修饰的成员变量只允许赋值一次,且只能在类方法赋值
C.final修饰的局部变量即为常量,只能赋值一次。
D.final修饰的方法不允许被子类覆盖
这是final最基础的问答题,如果想不明白原因建议往下看,干货满满。(可直接拉到最后查看答案)
🌲1.什么是final?
final是Java的一个基础关键字,它可以用来修饰类和方法以及变量。它的效果有点类似于C语言中的const。很多人想到final仅仅就觉得是加在变量前面不可变而已,没有深入理解final这个关键字存在的意义和注意事项。下面我讲分析它在变量、方法、类三处使用的作用。
🌲1.final修饰变量
🌰 1.final变量指向常用数据类型
我们都知道final修饰变量会有不可变性,但变量也分很多种,对于什么是不可变性我们也暂借不提,我们先来看看final来修饰成员变量以及局部变量但不对它们赋值的情况
☀️:我们发现成员变量a和d在声明时,未赋值的话会报错,会告诉你未在构造器中初始化。但局部变量b和c却没有报错,所以我们可以先记住:final修饰成员变量时必须赋值,而局部变量可以暂且不赋值。
🌰2.什么是final的不可变性?
说到不可变性,很多人肯定先想到String。但它和String的不可变性是有区别的(final和String可以搭配使用哦,下文会讲)。我们仍然用代码来演示
这里我们用局部变量来演示,final变量的b命名时我们并未赋值,它没有报错,然后我们给它赋值20,它也没有报错,当我们再次给它赋值时,我们发现它报错了。我们再看看另外一种情况:
左边当我们在未给b赋值时,直接使用b进行输出时,我们发现编译器报错了。但当我们给它赋值以后,编译可以正常调用b。通过上面的例子,我们可以得到结论:
✌️:final修饰的变量(无论成员变量还是局部变量),在使用前必须进行赋值,而且仅且只能赋值1次。如果多次赋值或者未赋值进行使用时,编译器将会提示错误。
上面是我们宏观的理解,我们通过内存的角度来分析final的不可变性:
我们列举出一个成员变量a和一个局部变量b。这里是为了顺便给大家讲下他们在内存的区别。当我们实例化类Test7时,有了一个引用变量a和一个值100(成员变量的值存在堆内存中)。a保存了100的地址,也就是指向了100。局部变量b被初始化后产生了一个a和10(局部变量的值在栈中),b指向了10。当我们尝试让a指向12和b指向200时,也就是要改变a和b的地址时,发现报错了。由此我们可以得知:
✌️:final的不可变性,指的是引用不可修改。我们都知道变量本身存储的是一个地方的地址,也就是这个地址不能修改,你指向了一个地方,那你这辈子都不能再指向别的地方了,这就是不可变性的意思。(但是被指向的地址里的内容是可以修改的,一定要记住!!!,和String的不可变性的不同,后续讲解)