final 声明方法,代表这个方法无法被子类重写
final声明类,代表这个类无法被继承
然后我们重点来说下final 修饰变量
在网上查了资料,final修饰的变量是只读的,其实我觉得并不是很准确,确切来说,final修饰的引用的地址是不变的.
接下来我们举几个例子来说明一下:
1.
public static void main(String[] args) { final String s="abc"; final StringBuilder sb=new StringBuilder("abc"); //s=s+"d"; //会报错 sb.append("d"); System.out.println(sb); /*output :"abcd"*/ }
结果:用final修饰的String不可变,但是用final修饰的StringBuilder变了.
原因:还是从存储方面来解释,变量s 和sb在栈区,指向的是"abc"(String)和"abc"(StringBuilder)在堆区的地址.当改变String的时候,会在堆区重新分配一个"abcd"的地址,然后将s指向"abcd"的地址,被final修饰之后地址不能变,所以会报错.同样的原因,"abc"(StringBuilder)变成"abcd"之后原地址不变(具体原因请翻我上面的博客),所以被final修是的StringBuilder的值是可变的.
2.然后我们来看下int为什么也是不可变的
public static void main(String[] args) { final int a =4; a=5;//重新赋值会报错 }
int (8种基础数据类型)的值称为字面值,存放在栈中,而a指向的是4的地址,当执行a=5的时候,他会先去找是否有5的地址,如果没有就开辟一个存放5这个字面值的地址,然后将a指向的地址换成5的地址,但是被final修饰之后地址不能变所以会报错.
这篇博客可能有侧重的写了对final 的理解,之后有相关的感悟会持续更新