final关键字的功能:修饰类、成员变量、方法。
其中成员变量包括实例变量和静态变量。
final修饰的类、成员变量、方法是不可变的。
01final修饰实例变量和静态变量
对于实例变量:
- 声明的时候进行初始化
- 通过构造器进行初始化
- 通过构造代码块进行初始化
public class FinalTest {
//直接给a赋值
public final int a = 2;
public final int b;
public final int c;
//构造器给b赋值
public FinalTest() {
b = 10;
}
//构造代码块给c赋值
{
c = 4;
}
}
对于静态变量:
- 声明的时候进行初始化
- 通过静态代码块进行初始化
注意:
final 和 static 一起修饰的成员变量叫做常量,常量名必须全部大写。
public class FinalTest {
//直接给age 赋值
public static final int age = 10;
public static final String NATION;
//通过静态代码块赋值
static {
NATION = "china";
}
}
如果没有进行初始化会出现下面错误:
final 修饰的基本数据类型变量和引用数据类型变量有什么区别?
final修饰的基本数据类型变量,一旦进行初始化,其值是不能更改的。
final修饰的引用数据类型变量,会不会发生改变呢?
public class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public static void main(String[] args) {
final Student stu = new Student(22, "张三");
stu.name = "李四";
System.out.println(stu.name);//李四
}
}
测试发现引用数据类型变量stu的name属性发生改变。
对于基本数据类型数值来说,初始化后值不能被修改。
对于引用数据类型来说,引用地址没有改变,一直指向这个对象,仅仅只改变对象的属性。
对于局部变量:
对局部变量age进行初始化后,不能修改其值。
public final void run() {
final int age;
age =19;
age =23;//编译不通过 age已经赋过值
}
final修饰的方法重载和重写有什么区别?
final修饰的方法可以重载。
代码如下:
public class FinalTest {
public String name;
public final void run() {
}
public final void run(String name) {
}
}
final修饰的方法为不可变方法,子类只能继承,不能进行重写。
代码如下:
public class FinalTest {
public final void run() {
System.out.println("这是一个final方法");
}
public void play() {
System.out.println("这是父类方法");
}
public static void main(String[] args) {
//子类继承了父类方法
new Zi().run();
}
}
class Zi extends FinalTest {
//子类重写没有被final关键字修饰的方法
@Override
public void play() {
super.play();
System.out.println("这是子类方法");
}
}
03final修饰类
final修饰的类,成为不可变类,子类无法继承父类。
应用场景:
当用final修饰类,该类不能被子类继承。