Java中的final关键字
final关键字在Java中指的是"无法改变的"。它作为数据,方法和类的修饰符号有如下作用。
修饰基本类型
数据以final修饰来告知编译器这是一块恒定不变的数据,比如:
1)一个永不改变的编译时常量
2)一个不希望被改变的运行时初始化的值
对于永不改变的编译时常量,编译器可能将该常量值直接代入计算式中
final int MAX = 20;
通常使用大写,多个单词以下划线分隔,其效果(不考虑作用域)可类比于c语言中的:
#define MAX 20
与static联用,该域将占据一个不能改变的存储空间。
static final int MIN = 0;
修饰对象引用
修饰的对象引用不可改变,即一旦引用被初始化指向一个对象,就不能再把它改变指向另一个对象。一个误区是,引用的对象本身不能改变。
public class Test { public static void main(String args[]){ final Person s1 = new Person(); Person s2 = new Person(); //s1 = s2; 报错,原因是s1是final修饰的对象引用 s2 = s1; //正确运行 s1.name = "Sakura"; //正确运行 } } class Person{ public String name = "sakura"; }
修饰方法
通常来说,修饰方法是为了把方法锁定,防止任何继承类修改它的含义。
class Person{ String name = "sakura"; public final void print(){ System.out.printf(name); } } class Student extends Person{ public void print(){ //报错,无法通过编译 System.out.printf(name); } }
修饰参数
在方法参数列表中以声明的方式将参数指定为final,代表在方法中无法改变参数指引的对象。
class Person{ public void print(final String str){ str = "sakura"; //无法通过编译,去掉final则正常运行 System.out.println(str); } }
修饰类
将某个类整体定义为final,即代表该类不能被继承。
final class Person{ String name = "sakura"; public final void print(){ System.out.printf(name); } } class Student extends Person{ //无法通过编译 }
注意,类被final修饰,不代表类中的域被final修饰,类中的域不被final修饰就代表该域可以被修改;即它的可修改性与类是否有final修饰无关。
public class Test { public static void main(String args[]){ Person s1 = new Person(); s1.name = "Sakura"; //运行正常 } } final class Person{ String name = "sakura"; public final void print(){ System.out.printf(name); } }
空白final
允许生成空白final,即未给定初值得final域;final修饰类中的某个域时,必须保证该域在定义时初始化或在构造器中被初始化。
class Person{ final String name; Person(){ name = "sakura"; } }