final修饰变量

前言:因为部门的需要,这段时间在招人,在和候选者沟通的时候,我发现一些人对于一个问题:变量被final修饰时它是不可变的,这个普遍的说法并不是十分的清楚本质,那就是----不变性究竟是指的什么是不变的。所以,才有了我今天这篇文章,希望可以给对这个问题不明白的人一些帮助。


好了,final修饰的变量究竟是怎么个不变性呢,这就开始进入主题吧。。。


很多人对于一个问题总是最关注简单直接的答案,而忽略其原理和过程,所以我这上来先把这个问题的答案给大家吧:


答案就是:对于final修饰的变量来说,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的,也就是说在对其初始化之后便不能再让其指向另一个对象。


答案就是这么简单,这就到了十字路口了,只喜欢答案的同学可以止步了,还想了解更多final对变量的机制的同学可以继续看下去,下面我将对final对变量的修饰做更全面的讲解。。。


一:final修饰的实例变量


1. 被final修饰的实例变量必须显示的指定初始值。
2. 对于普通实例变量,Java程序可以对它执行默认的初始化,也就是将实例变量的值指定为默认的初始值0或null,但对于final修饰的实例变量,则必须由程序员显示的赋予初始值。
3. final实例变量必须显示地被赋初始值,而且本质上final实例变量只能在构造器中被赋初始值。

        在定义final实例变量时指定初始值,和在初始化块中为final实例变量指定初始值本质上是一样的。除此之外,final实例变量将不能被再次赋值。


二:final修饰的类变量


对于final类变量而言,同样必须显示指定初始值,而且final类变量只能在2个地方指定初始值:
1. 定义final类变量时指定初始值;
2. 在静态初始化块中为final类变量指定初始值;

       这两种方式都会被抽取到静态初始化块中赋初始值。定义final类变量时指定初始值和在静态初始化块中为final类变量指定初始值,本质是一样的。除此之外final类变量将不能被再次赋值。


三:final修饰局部变量


       final修饰的局部变量一样需要被显式地赋初始值,因为Java本来就要求局部变量必须被显式地赋初始值。与普通变量不同的是,final修饰的局部变量被赋初始值之后,将不能再被重新赋值。


四:内部类中的局部变量


1. 这里不仅仅是匿名内部类,即使是普通内部类,在任何内部类中访问的局部变量都应该使用final修饰。
2. 此处说的内部类指的是局部内部类,只有局部内部类(包括匿名内部类)才可以访问局部变量,普通静态内部类、非静态内部类不可能访问方法体内的局部变量。
3. Java要求所有被内部类访问的局部变量都使用final修饰,对于普通局部变量而言,它的作用域就是停留在该方法内,当方法执行结束,该局部变量也随之消失。但内部类则可能产生隐式的”闭包“闭包将使得局部变量脱离它所在的方法继续存在。
4. 匿名内部类的实例生命周期没有结束的话,将一直可以访问局部变量的值,这就是内部类会扩大局部变量作用域的实例。
5. 由于内部类可能扩大局部变量的作用域,如果再加上这个被内部类访问的局部变量没有使用final修饰,也就是说该变量的值可以随意改变,就会引起大乱。

       因此Java编译器要求所有被内部类访问的局部变量必须使用final修饰。

总而言之:

1. final修饰符的第一简单的功能就是一旦被赋初始值,将不可改变。
2. final的另一个简单的功能就是在定义了该final类变量时指定了初始值,且该初始值可以在编译时就被确定下来,系统将不会在静态初始化块中对该类变量赋初始值,而将是在类定义中直接使用该初始化值代替该final变量。

3. 对于一个使用final修饰的变量而言,如果定义该final变量时就指定初始值,而且这个初始值可以在编译时就确定下来,那么这个final变量将不再是一个变量,系统会将其变成“宏变量”处理。所有出现该变量的地方,系统将直接把它当成对应的值处理。

好了,final修饰变量篇到此为止,如果问题可以留言,see you


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值