面试官Q1:请问String s = new String("xyz");产生了几个对象?

对于这个问题,老套路先上代码:

public class StringTest {
public static void main(String[] args){
String s1="Hello";
String s2="Hello";
String s3=new String("Hello");
System.out.println("s1和s2 引用地址是否相同:"+(s1 == s2));
System.out.println("s1和s2 值是否相同:"+s1.equals(s2));
System.out.println("s1和s3 引用地址是否相同:"+(s1 == s3));
System.out.println("s1和s3 值是否相同:"+s1.equals(s3));
}
}

打印结果如下

s1和s2 引用地址是否相同:true
s1和s2 值是否相同:true
s1和s3 引用地址是否相同:false
s1和s3 值是否相同:true

上面程序中的"=="是判断两个对象引用的地址是否相同,也就是判断是否为同一个对象,s1与s2 返回为true,s1与s3返回则是false。说明s1与s2 引用的同一个对象的地址,s3则与其它两个引用不是同一个对象地址。

Java为了避免产生大量的String对象,设计了一个字符串常量池。工作原理是这样的,创建一个字符串时,JVM首先为检查字符串常量池中是否有值相等的字符串,如果有,则不再创建,直接返回该字符串的引用地址,若没有,则创建,然后放到字符串常量池中,并返回新创建的字符串的引用地址。所以上面s1与s2引用地址相同。

那为什么s3与s1、s2引用的不是同一个字符串地址呢? String s3=new String("Hello"); JVM首先是在字符串常量池中找"Hello" 字符串,如果没有创建字符串常量,然后放到常量池中,若已存在,则不需要创建;当遇到 new 时,还会在内存(不是字符串常量池中,而是在堆里面)上创建一个新的String对象,存储"Hello",并将内存上的String对象引用地址返回,所以s3与s1、s2引用的不是同一个字符串地址。内存结构图如下:

从内存图可见,s1与s2指向的都是常量池中的字符串常量,所以它们比较的是同一块内存地址,而s3指向的是堆里面的一块地址,说的具体点应该是堆里面的Eden区域,s1跟s3,s2跟s3比较都是不相等的,都不是同一块地址。

了解了String类的工作原理,回归问题本身:

在String的工作原理中,已经提到了,new一个String对象,是需要先在字符串常量中查找相同值或创建一个字符串常量,然后再在内存中创建一个String对象,所以String str = new String("xyz"); 会创建两个对象。

下面两道题可以放在留言区回复哟:

String str1 = new String("A"+"B") ; 会创建多少个对象?
String str2 = new String("ABC") + "ABC" ; 会创建多少个对象? str1:字符串常量池:"A","B","AB" : 3个:new String("AB") :1个引用: str1 :1个总共 : 5个 str2 :字符串常量池:"ABC" : 1个:new String("ABC") :1个引用: str2 :1个总共 : 3个

最新文章

  1. python模块简介
  2. 跟着鸟哥学Linux系列笔记1
  3. HTML 标题<h1>-<h6>
  4. 《JAVA学习笔记(14-10---14-11抽象类)》
  5. NSOJ 鬼泣
  6. Java SE 6 新特性: 编译器 API
  7. HTTP协议中POST、GET、HEAD、PUT等请求方法以及一些常见错误 #Reprinted#
  8. HDoj-2084-号码塔-dp
  9. 程序编译没错,运行报错:无法定位程序输入点GT_BufLaserFollowRatio(这是函数)于动态链接库GTS.DLL上
  10. 正确理解Mysql的列索引和多列索引
  11. web前端教程:CSS 布局十八般武艺都在这里了
  12. python第三十一天-----类的封装、继承,多态.....
  13. nginx不浏览直接下载文件
  14. iOS - 沙盒机制(SandBox)和获取沙盒路径
  15. iOS10 完美降级 iOS9.3.2,保留全部数据
  16. linux 日志定时轮询流程详解(logrotate)
  17. POJ 2409 Let it Bead (Polya定理)
  18. 服务端模拟http服务请求客户端
  19. Java如何判断线程池所有任务是否执行完毕
  20. 【转】C++ 虚函数&纯虚函数&抽象类&接口&虚基类

热门文章

  1. [转] Java中public,private,final,static等概念的解读
  2. #2 codeforces 480 Parcels
  3. Docker 记一次容器内部修改宿主机挂载目录用户权限后宿主机目录变化
  4. BZOJ1295 [SCOI2009]最长距离 最短路 SPFA
  5. BZOJ1088 [SCOI2005]扫雷Mine 动态规划
  6. 020 Spark中分组后的TopN,以及Spark的优化(重点)
  7. hdu1003 Max Sum【最大连续子序列之和】
  8. 上线---苹果AppStore审核注意事项,Guideline 1.2 - Safety - User Generated Content,2.1等条例(苹果审核六次拒绝)
  9. Jmeter的安装和启动错误总结,出现unable to access jarfile apachejmeter.jar error value=1错误处理
  10. ubuntu安装nodejs出现./config.gypi错误