final从字面上理解含义为“最后的,最终的”。在Java中也同样表示出此种含义。
final可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
1、final修饰变量
当final修饰基本数据类型时,该变量就成为了常量,值无法改变;当final修饰引用数据类型时,该变量的值不能改变,即值中存储的对象内存地址值不变,该变量不能再去指向别的对象,但是对象内的成员可以改变。如下的程序示范了final修饰基本数据类型和引用数据类型的使用。
public class Person {
static String name = "王五";
int age = 20;
String country = "中国";
public void setAge(int age) {
this.age = age;
}
public void setCountry(String country) {
this.country = country;
}
}
public class FinalTest {
final static int number = 100;
public static void main(String[] args) {
// 下面的注释去掉后编译出错,final修饰的变量number无法再次赋值
// FinalTest.number=200;
final Person p1 = new Person();
Person p2 = new Person();
// 下面的注释去掉后编译出错,final修饰的变量p1无法再次赋值
// p1=p2;
p1.setCountry("Chinese");
p1.setAge(18);
System.out.println("p1.age的值为:" + p1.age);
System.out.println("p1.country的值为:" + p1.country);
}
}
FinalTest类定义了final修饰的基本数据类型的变量number的值为100,因此后面的程序无法更改它的值;随后FinalTest类用final来修饰Person类的对象p1,该变量为引用数据类型,无法更改该变量的值,即不能再将它指向另一个对象,因此语句“p1=p2;”会报错,因为无法将final修饰的对象p1指向另一个对象p2,但是不能改变的仅仅是变量p1中的引用值,对象内部还可以改变,本例程就通过Person的方法重新设置了Person类中变量age和country的值。
当final修饰变量时,由于在第一次赋值之后就无法改变,因此它的初始化就很重要,一般而言,我们对final变量的初始化可以在声明变量时、在类中的构造方法、在静态代码块中赋值。
2、final修饰方法
一个类中的方法如果被final关键字修饰,则其子类无法重写该方法,只能被子类继承。如果父类中的某个方法不想被其子类所覆写,可将该方法定义为final类型。另外,父类中的私有方法(即被private关键字修饰的方法)也不允许被子类所覆写,所以父类中被private关键字修饰的方法默认为final类型。
public class A {
public final void f1(){
System.out.println("Hello World");
}
}
public class B extends A{
//下面这行会报错Cannot override the final method from A
public void f1() {
System.out.println("你好");
}
}
3、final修饰类
final修饰类即表示此类已经是“最后的、最终的”含义。因此,用final修饰的类不能被覆盖,即不能拥有自己的子类。
public final class A {
}
//下面这行会报错The type B cannot subclass the final class A
public class B extends A{
}