面试题中关于String的创建和赋值的自己的理解

来源:互联网 发布:淘宝开宠物用品店 编辑:程序博客网 时间:2024/06/05 19:13
前几天在面试的时候,遇到了几道关于String的题目,发现自己对于字符串的创建、赋值的部分还有很多没有理解清楚的地方。

第一道面试题是说出以下程序的输出结果:

public static void main(String[] args) {String str="123";String str1=new String("123");String str2="123";System.out.println(str==str1);System.out.println(str==str2);}

我只当equals对于字符串是内容的比较,但是==又是怎么比较两个字符串对象是否相等的,当时隐约记得==是比较存储地址和内容是否都相当,但str与str2明明是创建了两个内容为“123”的字符串,存储地址应该不一样吧,好后悔以前用到的时候不求甚解,在网上查找资料,通过两位大神的资料得到了答案。
原文地址:http://www.cnblogs.com/dolphin0520/p/3592500.html

原文地址:https://my.oschina.net/Chaos777/blog/309476


通过上面两篇文章我们知道,对于==符号,分为两种情况

当比较的对象是基本数据类型时,==直接比较两者的数值是否相等

当比较的对象是非基本数据类型,比如String这种引用类型,==比较引用对象所在的内存地址是否相同。

上面这道题,str引用了“123”这个字符串,str1使用new关键字,新创建了一个字符串对象,尽管str和str1的内容是相同的,但是引用的内存地址是不同的。

接下来问题又来了,str和str2都是赋值为"123",那么它们两者引用的对象所在的内存空间是一致的嘛,这就涉及到String类型在java的创建和缓存机制了

String是不可变类,因此它是可以被共享的

编译期间,JVM会把已出现的字符串常量放入字符串缓存池当中(不包括通过变量或者方法才可以得到的字符串,因为这些在运行期间才可以得到),当创建一个String对象,首先查看缓存池中是否有相同的字符串,如果有则指向这个字符串对象的地址处。

因此,上面这道题中str与str2所对应的字符串都是“123”,它们引用的字符串地址也是一样的。


但是String是不可变类,如果将一个字符串变量赋值给两一个字符串,之前的字符串常量还会继续存在于缓存池中,而不会被垃圾回收机制释放,因此过度使用String类型会导致内存泄露的问题出现,这时候我们可以使用StringBuffer和StringBuilder来解决这一问题。

StringBuffer和StringBuilder在操作字符串的时候,是在同一个对象上进行操作的,而且StringBuffer是线程安全的,StringBuilder不是