final关键字
在java中,final的含义在不同的场景下有细微的差别,但总体上来说,它指的是“这是不可变的”。下面,结合例子简单记录下final关键字的用法
场景1:当final修饰基本数据类型变量时, 一旦变量的值被初始化后, 则不允许被二次赋值
/**
* 场景1:
* 当final修饰基本数据类型变量时, 一旦变量的值被初始化后, 则不允许被二次赋值
*/
private void case1(){
final int i = 0;
// i = 1; error: Cannot assign a value to final variable "i"
final short s = 0;
// s = 0; error: Cannot assign a value to final variable "s"
final long l = 0L;
// l = 0L; error: Cannot assign a value to final variable "l"
final byte b = 0;
// b = 0; error: Cannot assign a value to final variable "b"
final float f = 0;
// f = 0; error: Cannot assign a value to final variable "f"
final char c = 's';
// c = 's'; error: Cannot assign a value to final variable "c"
final double d = 0d;
// d = 0d; error: Cannot assign a value to final variable "d"
final boolean bol = false;
// bol = true; error: Cannot assign a value to final variable "bol"
}
场景2:当final修饰引用型变量时, 则对变量初始化后不能再指向另外一个对象
/**
* 场景2:
* 当final修饰引用型变量时, 则对变量初始化后不能再指向另外一个对象,但是可以修改对象的成员变量值
*/
private void case2(){
final FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
FinalDemoA finalDemoB = new FinalDemoA();
// finalDemoA = finalDemoB; Cannot assign a value to final variable "finalDemoA"
// finalDemoA = new FinalDemoA(); Cannot assign a value to final variable "finalDemoA"
finalDemoA.value = 2;
}
场景3:当final修饰方法入参变量时, 该入参变量在方法作用域内不允许再指向另外一个对象, 但是可以修改对象的成员变量值,原理与场景2相同
public static void main(String[] args) {
FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
case3(finalDemoA);
System.out.println("in main Method finalDemoA.value = " + finalDemoA.value);
}
/**
* 场景3:
* 当final修饰方法入参变量时, 该入参变量在方法作用域内不允许再指向另外一个对象, 但是可以修改对象的成员变量值
* 原理同场景2相同
*/
private static void case3(final FinalDemoA finalDemoA){
FinalDemoA finalDemoA1 = new FinalDemoA();
// finalDemoA = finalDemoA1; Cannot assign a value to final variable "finalDemoA"
// finalDemoA = new FinalDemoA(); Cannot assign a value to final variable "finalDemoA"
finalDemoA.value = 2;
System.out.println("in Case3 Method finalDemoA.value = " + finalDemoA.value);
}
-----------------------------------------------------
in Case3 Method finalDemoA.value = 2
in main Method finalDemoA.value = 2
场景4:被final修饰的变量作为方法入参时, 由于方法入参没有被final修饰, 故在方法体内可以将该变量指向另外一个对象, 当方法运行结束后, 该final变量将仍指向原对象而不是新对象
public static void main(String[] args) {
final FinalDemoA finalDemoA = new FinalDemoA();
finalDemoA.value = 1;
System.out.println("in main Method finalDemoA.address = " + finalDemoA);
case4(finalDemoA);
System.out.println("in main Method finalDemoA.address = " + finalDemoA);
System.out.println("in main Method finalDemoA.value = " + finalDemoA.value);
}
/**
* 场景4:
* 被final修饰的变量作为方法入参时, 由于方法入参没有被final修饰, 故在方法体内可以将该变量指向另外一个对象,
* 当方法运行结束后, 该final变量将仍指向原对象而不是新对象
*/
private static void case4(FinalDemoA finalDemoA){
finalDemoA = new FinalDemoA();
finalDemoA.value = 2;
System.out.println("in Case4 Method finalDemoA.address = " + finalDemoA);
System.out.println("in Case4 Method finalDemoA.value = " + finalDemoA.value);
}
-------------------------------------------------
in main Method finalDemoA.address = FinalDemoA@244038d0
in Case4 Method finalDemoA.address = FinalDemoA@5680a178
in Case4 Method finalDemoA.value = 2
in main Method finalDemoA.address = FinalDemoA@244038d0
in main Method finalDemoA.value = 1
场景5:用final关键字修饰方法,它表示该方法不能被覆盖。类中所有的private方法都隐式地指定为是final的
场景6:final修饰的类是无法被继承的。
上面我们讲解了final的几种用法,然而,对于第五种和第六种用法,我们却甚少使用。这不是没有道理的,从final的设计来讲,这两种用法甚至可以说是鸡肋,因为对于开发人员来讲,如果我们写的类被继承的越多,就说明我们写的类越有价值,越成功。即使是从设计的角度来讲,也没有必要将一个类设计为不可继承的。