以下都是个人见解,如果有错误,希望能指出来,我会修改的。
【final】可修饰类,方法,变量。
如果修饰类,则该类无法被继承。
如果修饰方法,改方法无法被重写。
如果修饰的是基本数据类型变量,则该无法被赋予其他值。
如果是引用数据类型变量,那么得具体讨论。
例如String和StringBuffer。

【不可变】简单来说,当字符串一旦创建时,该字符串就不可改变。不可变指的是不可直接修改堆中内容(对象值不能改变),但可以修改栈中内容(引用地址可以改变)。
网友【wang_rh】的说法更加详细一些:
【不可变指的是不可直接修改堆中内容,但可以修改栈中内容(即可以修改引用)。即String t=new String(“abc”); t=“abcd”;修改的不是“abc”这个字面量。而是修改了t的引用(即栈中存储的内容)。所以代码执行后实际t已经不再是指向之前的对象了。】
例如:
// String s1="abc";
//s1="123";
这里,创建了对象"abc",引用s1指向对象"abc"。【不可变是指"abc"无法改变,但是引用s1是可以改变,即可以指向其他字符串对象,例如"123"。】
【String为什么不可变】在JDK14 java.lang.String 源码。
如下:
// String码源 其中的片段
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
@Stable
private final byte[] value;
String被final修饰,说明该类不可继承。
byte[] value被final修饰,说明value的引用在创建之后不能被改变。
// String s="abc";//以该代码为例,简单谈一下我个人的理解。
简单来说,解释Spring不可变就是解释"abc"是"abc",而无法变成"abcd"。
注意:不可变是指"abc"字符串创建后,【“abc"字符串】永远无法改变,不是指引用s永远指向"abc”。
①首先创建了一个byte[] 数组,把"abc"放入数组。数组一旦创建,类型和长度无法改变。
②value被final修饰,value是引用,value所指向的内存地址不可变(永远指向"abc"所在的byte[]数组),不可以指向其他对象。
三,value被private修饰,只能本类访问,无法被子类,同包等外部程序直接访问访问。![]()
④有了保护性拷贝,不允许直接赋值给数组byte[],所以数组存储的是"abc"无法改变值。
【总结】value指向的地址无法改变,指向地址的对象类型无法改变,长度无法改变,对象的值无法改变。所以String是不可变的。
由于本人入门较晚,水平有限,如果有错误希望大佬能指出,为了照顾广大初学者,尽量解释的浅显易懂一些,十分感谢。