探究java new String()究竟创建几个对象? - Go语言中文社区

探究java new String()究竟创建几个对象?


new String()究竟创建几个对象?

1、由来

遇到一个java面试题,是关于String的,下面是题目的描述:

//在java中,new String("hello")这样的创建方式,到底创建了几个String对象?

2、解答

2.1.分析

​ 题目中的String创建方式,是调用String的有参构造函数,而这个有参构造函数的源码是这样的public String(String original),这就是说,我们可以把代码转换成下面这种:

String temp = "hello"; //在常量池中
String str = new String(temp); //在堆上

这段代码就创建了2个String对象,temp指向常量池中的,str指向堆上,而str内部的char value[]则指向常量中的char value[],所以这里的答案是2个对象。

那为什么说答案是一个的也对呢,假如就只有一句String str = new String("hello");并且此时的常量池的没有"hello"这个String,那么答案是对的;如果此时常量池中,已经存在"hello"常量,那么此时就只创建堆上的str,而不会创建常量池中的temp(注意这里是引用),所以此时答案是1个。

2.2、验证
不啰嗦,直接看第一段代码
public static void main(String[] args){
  String str = new String("hello");
  
  String after_str = "hello";
  
  System.out.println(str + after_str);
}

现在我们在println语句那里加个断点,debug下,如下图:
1288700-20180129165334546-2112253881.png

可以看到在代码中,str和after_str不是同一个对象,这个应该没有疑问吧,一个在堆上,一个在常量池中。但是我摩恩可以注意到str.value和after_str.value的地址的确是同一个,即是同一个char数组,所以可以理解为,当执行str那句代码时,创建了两个String对象,一个在常量池,一个在堆上,加下来到执行after_str这句时,这种方式创建的字符串都在常量池中,但是如果常量池已经存在这个字符串则直接返回了,所以这里返回的是上一句在常量池那里创建的String,所以str这里创建了两个对象。

接下来再看一段代码:

public static void main(String[] args){
  String before_str = "hello";
  
  String str = new String("hello");
  
  System.out.println(str + before_str);
  
}

同样在println打断点,如下图:
1288700-20180129165348687-1069065241.png

代码2中,str.valuebefore_str.value也是用的同一个char数组,但这里的代码可不是和代码1相同的,这里我们把"hello"提到前面创建,这也就是说明当执行str那句代码时,没有再在常量池中创建"hello"了,所以str这句则是创建了1个对象。

2.3、补充

这里补充一下上面 如果常量池中没有,则创建二个对象这个概念,这里很多人会误解这句话的含义,这个常量池不是你手动的创建,常量池中就没有东西。这个理解是错误的,一定要修正这个观念。在你的程序启动时,就已经装载了很多class,这里面也有字符常量的创建,只是不是你自己创建的,你不知道创建了而已。

转载于:https://www.cnblogs.com/linjianqing/p/8378225.html

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/diaobi4377/article/details/102227721
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 15:28:26
  • 阅读 ( 1034 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢