首先,final可以修饰基本类型的变量,也可以修饰引用类型。
那么,final修饰的变量的值真的不可以改变吗?先看下面的代码:
class Test {
public static void main(String[] args) {
A a=new Test().new A();
A c=new Test().new A();
final A b = a;
System.out.println(b.val);
a.val = 200;
System.out.println(b.val);
b.val = 300;
System.out.println(b.val);
}
class A {
int val = 100;
}
}
运行结果:
100
200
300
具体看下图进行分析:
首先用通俗易懂的语言解释一下几个名词:
引用变量:存储引用的变量,作用就是存放引用
引用:指向某个对象地址的方向标,有了某个对象的引用,就可以访问这个对象
引用类型:初学者遇到的只要是能用new关键字造出来的实例都是,比如数组,字符串,以及其他各种类的实例。
如上边左图所示,给引用变量赋值A对象,实际上就是把对象A的引用存入这个引用变量,然后我们就可以通过这个引用变量去操作对象A,如果我们再把对象B赋值给这个引用变量,那么实际上就是用B的引用去替换了引用变量中原本存放的A的引用,所以现在可以使用引用变量访问对象B,而不能访问对象A。
而上边右图所示,如果把对象A的引用存入这个final修饰的引用变量之后,引用变量就变为引用常量。不能再存储新的引用,也就是说无法把B的引用存入这个引用常量。但是我们可以通过A的引用去改变这个引用所指向的地址的内容!
所以final修饰的变量可以这么理解:修饰基本类型值不变,修饰引用类型只是引用不可变,但是引用所指向的地址的内容可以改变。