String s="Hello"; s=s+“world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?
没有。因为String是不可变类(immutable class),不可变类,顾名思义就是说类的实例是不可被修改的。实例的信息是在创建的时候提供,并且在整个生命周期中都不可改变。在这段代码中,s原来指向一个String对象,内容是“hello”,然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为”helloworld!",原来那个对象还存在内存中,只是s这个引用变量不再指向他了。
通过上面的说明,我们很容易得出一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为,String对象建立后不能改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,他允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
是否可以继承String类?
String类是由final关键字修饰的,故不可以被继承。
String共创建几个对象(String str = "ab" +"cd";)
代码片段1:
String str1 = "ab";
String str2 = "ab";
//str1==str2 为true
代码片段2:
String str3 = new String("ab");
String str4 = new String("ab");
//str3==str4 为false
代码片段3:
String str5 = "ab"+"cd";
代码片段1:
String str1 = “ab”;在字符串常量池创建一个对象"ab",后面str2时直接引用该对象,不用再创建,共创建一个对象
代码片段2:
先在字符串常量池创建一个对象"ab",然后在堆空间创建两个对象,使str3和str4分别指向它们,共创建3个对象
代码片段3:
在字符串常量区创建3个对象,分别是"ab" ,“cd”,“abcd”
String s=new String("XYZ")请问创建几个对象
两个,一个是存储在堆上的XYZ,一个是存储在栈上的S变量,S存储的是XYZ在堆上的首地址。
原文:https://blog.csdn.net/qq_36336003/article/details/82820845