value被声明为final类型,这意味着 value 数组初始化之后就不能再引用其它数组,并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。
不可变的好处: 可以缓存 hash 值: 因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。String Pool 的需要: 如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。如下图: 我的理解:比如说 String myName = "Cherish";这个Cherish字符串一旦被创建,就会存到内存上某个地址如 0x58 处,然后这个字符串会被放到String Pool中,之后你再传建一个 String yourName = "Cherish",那么,这个yourName将不会重新分配一块内存并把Cherish存进去,而是,直接指向前面创建的 “Cherish”的内存,以后无论你创建多少个 “Cherish”字符串,他都是指向最初的那个“Cherish”的地址。如下图: 另一边,如果我改变myName的值,则原来保存的值不会改变,而只会另外开辟一块空间,把改变后的字符串存进去,如下图: 安全性: String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。线程安全: String 不可变性天生具备线程安全,可以在多个线程中安全地使用。2.线程安全
String 不可变,因此是线程安全的StringBuilder 不是线程安全的;StringBuffer 是线程安全的,内部使用 synchronized 进行同步;
执行 + 的时候,首先,底层会创建一个 new StringBulider()对象,然后调用该对象的append()方法,来拼接“abc” 和 “EF”. ==> new StringBuilder().append(str1).append("EF");
如果继续拼接其他的字符串时,又会继续创建 new StringBuilder(),继续拼接,每次拼接一个,都新建一个对象,这些对象存放在堆中。
public static void main(String[] args) { String str1 = "abc"; str1 = str1+"EF"; String str2 = "abcEF"; String str3 = "abcEF"; String str4 = new String("abcEF"); System.out.println(str1 == str2); System.out.println(str1.equals(str2)); System.out.println(str2 == str3); System.out.println(str2 == str4); }
final关键字(拓展)
final关键字:在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局?> 部变量):
修饰类: 修饰类当用final去修饰一个类的时候,表示这个类不能被继承。注意: a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。 b. final类中的成员方法都会被隐式的指定为final方法。
修饰方法: 被final修饰的方法不能被重写 使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。 因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。 一个类的private方法会隐式的被指定为final方法修饰变量: 当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象(也就是地址不能改变)了,但该引用所指向的对象的内容是可以发生变化的;final修饰一个成员变量(属性),必须要显式初始化; final变量和普通变量的区别: 一段代码: public class Test { public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); //true System.out.println((a.equals(e))); //true System.out.println((a == e)); //false } }
转载于:https://www.cnblogs.com/CherishTheYouth/p/CherishTheYouth_2019_0726.html