一、关键字 final
final 修饰符可以用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
1.1 final 变量
final 有"最后的、最终的"的含义,final 修饰的变量一旦被赋值后,就不能被重新赋值。此外,被 final 修饰的实例变量必须显式指定初始值(可以理解为,未初始化的值为常量的话没有意义)。修饰常量时,关键字 final 就和 C++ 中的 const 关键字的功能比较相似了。不过要注意的一点是,final 修饰的引用变量,其指向的对象的内容是可以被改变的。
importjava.util.ArrayList; classTest { publicstaticvoidmain(String[] args) { finalArrayList<String>arrayList=newArrayList<>(); arrayList.add("1"); // 并不会报错,指向对象的内容可以改变arrayList.add("2"); arrayList.forEach(a->System.out.println(a)); finalintconstant=1; // constant = 2; // 这样写会报错:java: 无法为最终变量constant分配值 } }
1.2 final 方法
根据 final 的含义,我们可以这样理解,final 修饰的方法,是最后的方法,不可被重新定义(重写),但是可以被子类继承。final 修饰方法的主要目的是防止该方法的内容被修改,类似于 final 修饰变量后变成常量。
1.3 final 类
final 修饰的类无法被继承,也相当于无法被修改,同时,final 类中的所有成员方法都将隐式地被 final 修饰。Java 中最经典 final 修饰的类就是 String 了,它无法被任何类继承,不仅仅是为了保证 String 的不变性,同时在早期的 Java 版本中会将 final 修饰的方法转化为内嵌调用,提高程序性能(后来的 Java 会自动进行优化,不需要显式地用 final 修饰)。
二、关键字 static
static 修饰符可以用来修饰类方法和类变量。
2.1 静态变量
当 static 关键字用来声明独立于对象的静态变量时,无论一个类实例化多少对象,它的静态变量都只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。这个和 Python 中 class variable(类变量)有异曲同工之妙。
publicclassTest { publicstaticvoidmain(String[] args) { MyClassc1=newMyClass(); MyClassc2=newMyClass(); System.out.println(c1.var); // Output: 1c1.var=2; System.out.println(c2.var); // Output: 2 } } classMyClass { publicstaticintvar=1; }
2.2 静态方法
当 static 关键字用来声明独立于对象的静态方法时,该静态方法不能使用其类的非静态变量。这和 Python 的 staticmethod(静态方法) 有异曲同工之妙。虽然静态方法无法访问其类的非静态变量,但是静态方法仍有其作用,它可以作为一种辅助方法,处理由参数传入的数据,并返回。
三、final 和 static 的区别和联系
3.1 联系
关键字 final 和 static 都属于 Java 的非访问修饰符,都是为了实现某一特定功能而存在的。
3.2 区别
经常有人会把这两者混淆,尽管它们经常一起配合使用来创建常量,但它们的功能完全不一样。简单点说,final 只是保证无法被改变,static 保证只存在一个副本。