写在前面:
视频是什么东西,有看文档精彩吗?
视频是什么东西,有看文档速度快吗?
视频是什么东西,有看文档效率高吗?
1. new String()
诸小亮:String 类也提供构造函数,用来创建对象
张小飞:是 new String() 吗?
诸小亮:是的,不过,一般不建议使用这种方式,可能会造成问题
张小飞:会有什么问题?
“看下面代码”
public static void main(String[] args) throws Exception {
String str = "aaa";
String str2 = new String("aaa");//使用 new 创建对象
System.out.println(str2 == str);
}
结果:
张小飞:str 和 str2 不是同一个字符串吗?
诸小亮:是同一个字符串,但是使用 new String() 后,现在 str 和 str2 指向不同内存: ”
张小飞:不对啊,‘aaa’在内存中不应该只有一份儿吗?
诸小亮:你说的不错,具体给你解释一下
- 堆内存中有一块儿区域叫字符串常量池,我们定义的字符串都会放到这个常量池中
- 执行 String str = “aaa” 时,先去看常量池中有没有,没有就放进去
- 执行:String str2 = new String(“aaa”)时,"aaa"已经在常量池中,直接使用它创建 String 对象
- 但 new String() 会在堆内存中开辟空间,str2 指向的是新开辟的空间
张小飞:明白了,也就是说 str 和 str2 内容一样,但是指向不同的地址
诸小亮:是的,所以这时候应该使用 equals 方法,比较它们是否一样
总结:如果比较两个字符串是否一样,一定要用 equals 方法
2. 面试
诸小亮:曾经有个面试题,问: new String(“aaa”) 创建了几个对象?
张小飞:按照上面的说法,应该是 2 个吧
诸小亮:准确来说是 1个或2个
张小飞:额…,明白了,当 “aaa”不在常量池,就创建了 2 个
当 “aaa”已经在常量池,那么就创建了 1 个
诸小亮:完全正确,另外,我们也可以通过查看内存去证明
张小飞:嗯嗯,这时候 new String(“aaa”) 只是创建了一个 String 对象
诸小亮:如果没有提前定义 str = “aaa”
张小飞:明白了