转载:https://blog.csdn.net/u012514113/article/details/129217902
一. 概述
final关键字代表最终,不可改变的.
常见有5种用法,我们来归纳总结一下:
- 1. 用来修饰一个类
- 2. 用来修饰一个方法
- 3. 用来修饰成员变量
- 4. 用来修饰局部变量
- 5. 用来修饰方法参数
二. final饰修类
如果声明一个类为final类, 那么这个类就是最终类,不能被继承
public final class ParentClass { public void happy() { System.out.println("高兴"); } }
当写一个类去继承它的时候
public class ChildClass extends ParentClass{ }
就会提示如下错误:
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写.
三. final修饰方法
当final用来修饰一个方法的时候,这个方法就是最终方法,那么很明显就是说不能被覆盖重写。
public class ParentClass { public void happy() { System.out.println("高兴"); } //用final关键字修饰的方法 protected final void play(){ System.out.println("开心的玩耍"); } }
我们在继承类中去看下 play()方法是否可以被override
也是报错,说明 final修饰的方法,是一个最终方法,不能被子类去覆盖重写.
四. final修饰成员变量
在java中,成员变量一般都有默认值, 比如 int 型变量,默认值为0 boolean型变量默认值为false
String型变量,默认值为null
我们来看上面的例子, 3个同样类型的 int型 成员变量, number temp 默认值都是0 , 写和没写都没有报错. 但是加上final之后的num变量,没有初始化就报错.
总结一: 由于成员变量具有默认值,但是用了final关键字修饰之后必须要手动赋值初始化值.
我们再看一个例子
总结二: 对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可被改变。
五. final修饰局部变量
对于基本类型来说,不可变说的是变量当中的数据不可改变;
请看如下例子:
对于引用类型来说,不可变指的是变量当中的地址值不可改变
我们再来看下个例子,
Student为一个普通的javabean类
private String name; public Student() { } public Student(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
第一种情况,没有final修饰的测试类
public class FinalVarTest { public static void main(String[] args) { Student student1 = new Student("勒布朗.詹姆斯"); System.out.println(student1); //打印内存地址 System.out.println(student1.getName()); student1 = new Student("斯蒂芬.库里"); System.out.println(student1); //打印内存地址 System.out.println(student1.getName()); } }
打印结果如下:
com.finaltest.Student@4aa298b7 //内存地址 勒布朗.詹姆斯 com.finaltest.Student@7d4991ad //内存地址 斯蒂芬.库里
输出结果:内存地址不同
第二种情况: 使用final修饰测试类
若用final修饰,地址值不可以被改变,否则直接报错.
地址值虽然不能变,但是内容可以变(地址所指向的对象的属性可以被该变)。
请看如下例子:
public class FinalVarTest { public static void main(String[] args) { //使用final修饰的对象 final Student student2 = new Student("詹姆斯.哈登"); System.out.println(student2); //打印内存地址 System.out.println(student2.getName()); student2.setName("安东尼.戴维斯"); System.out.println(student2); //打印内存地址 System.out.println(student2.getName()); } }
打印结果如下:
com.finaltest.Student@4aa298b7 詹姆斯.哈登 com.finaltest.Student@4aa298b7 安东尼.戴维斯
两者的内存地址是相同的,但是名字(属性)是可以修改的.
六. final修饰参数
在方法参数前面加final关键字就是为了防止数据在方法体中被修改。
主要分两种情况:第一,用final修饰基本数据类型;第二,用final修饰引用类型。
第一种情况,修饰基本类型(非引用类型)。这时参数的值在方法体内是不能被修改的,即不能被重新赋值。否则编译就通不过。例如:
第二种情况,修饰引用类型。这时参数变量所引用的对象是不能被改变的。作为引用的拷贝,参数在方法体里面不能再引用新的对象。否则编译通不过。例如:
但是对于引用,如果我是这样(也就是引用对象的地址不能改变,但是对象中的内容是可以改变的),则不会报任何错,完全能编译通过。
public class FinalVarTest { public static void main(String[] args) { String[] var = {"张三","李四", "王五"}; valid(var); } public static void valid(final String[] ag){ ag[2]= "赵六"; for(int i=0; i<ag.length; i++) { System.out.println(ag[i]); } } }
编译通过,打印如下:
张三 李四 赵六