一. 概述
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类
public class Student {
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]);
}
}
}
编译通过,打印如下:
张三
李四
赵六