欢迎关注头条号:Java小野猫
在Java中,final关键字可以用来修饰类、变量(包括成员变量和 局部变量 )、方法,下面从这三个方面分别说明。
final方法
当一个方法被final修饰时,表明这个方法不能被子类重写。
下面程序试图重写final方法,将会引发编译错误。
public class Dinosaur { public final void test() { } } public class Further extends Dinosaur { // 下面代码会编译错误,不能重写final方法 public void test() { } }
特别的,类中的所有 private 方法都被隐式地指定为是final的。
final类
当一个类被final修饰时,表明该类不能被继承。若一个类试图继承一个final类时,将会编译错误。
// 定义一个Dinosaur类,并声明为final的
public final class Dinosaur {
//...
}
// 当 Further 试图继承Dinosaur,编译会不通过
public class Further extends Dinosaur {
}
由于final类不能被继承,所以final类中所有的方法都隐式地指定为final的。你也可以给这些final类中的方法加上fianl修饰符,不过这样做没有任何意义。
像我们常用的String类,就是被设计成final的,它不能有子类。
final变量
变量分为成员变量和局部变量,下面分别说明。
- final成员变量
当一个成员变量被final修饰时,表明这个变量完成初始化(实例变量:要么在定义该实例变量时指定初始值,要么在普通初始化块或 构造器 中指定初始值;类变量:要么在定义该类变量时指定初始值,要么是在静态初始化块指定初始值)后,就不能被改变。
下面程序代码演示final修饰成员变量的效果。
public class FinalVariableTest { // 定义成员变量时指定初始化值 private final int a = 6; // 定义成员变量时未指定初始化值,将在构造器中进行初始化 private final String s; public FinalVariableTest() { // 初始化s的值,如果不初始化s的值,将会编译错误,final修饰的成员变量必须由程序显式地指定初 // 始化值 this.s = "程序员技术之瞳"; // ERROR,这里试图给a重新赋值,将会编译错误 a = 7; } }
- final局部变量
如果final修饰的局部变量在声明时已经赋了初始值,则后面代码中不能再重新赋值。
public void test() { // 这里定义一个final的局部变量,并赋了初始值1 final int a = 1; // ERROR,试图重新赋值,则会编译错误 a = 2; }
如果final修饰的局部变量在声明时未指定初始值,则后面代码中可以给该变量赋值,但 只能赋值一次 。
public void test() { // 这里定义一个final的局部变量,但没有指定初始值 final int a; // 给变量赋值为1 a = 1; // ERROR,这里若试图给a重新赋值,则会编译错误 a = 2; }
final修饰基本数据类型变量和引用类型变量的区别
当final修饰的是基本数据类型变量时,该变量一旦获得初始化值,其值将无法改变。
当final修饰的是引用数据类型变量时,由于该变量保存的是一个地址值,final保证的是该变量不会引用另外一个对象,但该对象的内容可以改变。
欢迎做Java的朋友们私信我【资料】免费获取免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、 Jvm 性能调优、Spring源码, MyBatis , Netty ,Redis,Kafka,Mysql, Zookeeper ,Tomcat,Docker, Dubbo ,Nginx等多个知识点的架构资料)
其中覆盖了互联网的方方面面,期间碰到各种产品各种场景下的各种问题,很值得大家借鉴和学习,扩展自己的技术广度和知识面。