Java之final修饰变量

原创 2016年05月31日 15:25:20


final修饰的实例变量

被final修饰的实例变量必须显示指定初始值,而且只能在如下3个位置指定初始值:
1.定义final实例变量时指定初始值;
2.在非静态初始化块中为final实例变量指定初始值
3.在构造器中为final实例变量指定初始值
对于普通实例变量,Java程序可以对它执行默认的初始化,也就是将实力变量的值指定为默认的初始值0或null,但对于final实例变量,则必须由程序员显示指定初始值。
final实例变量必须显示地被赋初始值,而且本质上final实例变量只能在构造器中被赋初始值。在定义final实例变量时指定初始值,和在初始化块中为final实例变量指定初始值本质上是一样的。除此之外,final实例变量将不能被再次赋值。

final修饰的类变量

对于final类变量而言,同样必须显示指定初始值,而且final类变量只能在2个地方指定初始值:
定义final类变量时指定初始值;
在静态初始化块中为final类变量指定初始值;
这两种方式都会被抽取到静态初始化块中赋初始值。定义final类变量时指定初始值和在静态初始化块中为final类变量指定初始值,本质是一样的。除此之外final类变量将不能被再次赋值。

final修饰局部变量

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

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

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

执行“宏替换”的变量

对于一个final变量,不管它是类变量、实例变量还是局部变量,定义了该变量时使用了final修饰符修饰,并在定义该final类变量时指定了初始值,而且该初始值可以在编译时就被确定下来,那么这个final变量本质上已经不再是变量,而是想当于一个直接的变量。
final修饰符的一个重要用途就是定义“宏变量“,当定义final变量时就为该变量指定了初始值,而且该初始值可以在编译的时候就确定下来,那么这个final变量本质上就是一个”宏变量“,编译器会把程序中所用到该变量的地方直接替换成该变量的值。如果被赋的表达式只是基本的算术运算表达式或字符串连接运算,没有访问普通变量,调用方法,Java编译器同样会将这种final变量当成”宏变量“处理。

对于实例变量而言,可以在定义该变量时赋初始值之外,还可以在非静态初始化块、构造器中对它赋初始值,在这三个地方指定初始值的效果基本一样。但对于final实例变量而言,只有在定义该变量时指定初始值才会有”宏变量“的效果,在非静态初始化块、构造器中为final实例变量指定初始值则不会有这种效果。对于普通类变量而言,在定义时指定初始值,在静态初始化块中赋初始值的效果基本一样。但对于final类变量而言,只有在定义final类变量时指定初始值,系统才会对该final类变量执行”宏替换“


final方法不能重写
当final修饰某个方法时, 用于限制该方法不可被它的子类重写。
如果父类中某个方法使用了final修饰符进行修饰,这个方法将不可能被子类访问到,因此这个方法也不可能被它的子类重写。private和final同时修某个方法是没有太大意义,但是被Java语法允许。
如果父类和子类没有处于同一个包下,父类中包含的某个方法不使用访问控制符(相当于包访问权限)或者仅使用private访问控制符,那子类也是无法重写该方法的。

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


版权声明:本文为博主原创文章,未经博主允许不得转载。

java的final关键字——修饰变量

一、final修饰变量 final修饰变量不可变,这里是指引用不可变(Java中共提供两种数据类型,原始数据类型8种和引用类型),即它只指向初始时指向的那个对象,而不关心指向对象内容的变化。 fina...

final修饰的变量是引用不能改变还是引用的对象不能改变

使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。...

Static和final修饰变量、方法、类的时候含义分别是什么?

一、final  根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。 fin...

final修饰基本类型和引用类型变量的区别

当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型的变量而言,它保存的仅仅是一个引用,final只保证这个引用所引用的地址不会改变,即一直引用同...

java中的final变量

【java中为什么会有final变量】: final这个关键字的含义是“这是无法改变的”或者“终态的”; 那么为什么要阻止改变呢? java语言的发明者可能由于两个目的而阻止改变: 1).效率问题: ...

java中的final变量

【java中为什么会有final变量】:    final这个关键字的含义是“这是无法改变的”或者“终态的”;    那么为什么要阻止改变呢?    java语言的发明者可能由于两个目的而阻止改变: ...

Java-实例变量、局部变量、类变量与final变量的区别

把Java中的实例变量、局部变量、类变量与final变量之间的关系的思路重新整理一遍。俗话说的好“好记忆不如烂笔头”,在此分享一下。...

Java final关键字用来修饰类、方法、属性

1.final修饰类:这个类不能被继承。如:String类、StringBuffer类、System类。 2.final修饰方法:不能被重写。如:Object类的getClass()方法。 3.f...

java中final修饰方法传入参数的影响

最近在看spring 源码深度解析 看到了许多方法中的参数被final修饰符修饰 什么作用自己蒙了 难道在方法中不允许修改参数么 网上查了查 恍然大悟 final类型修饰的参数分为两种类型 基本类...

Java final修饰类/方法/变量的特点

public class Demo_Final { public static void main(String[] args) { // Son6 s=new Son6(); ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java之final修饰变量
举报原因:
原因补充:

(最多只允许输入30个字)