A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 君嘘 中级黑马   /  2015-4-17 16:48  /  843 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

先来看这个
String a="abc".
这段代码编译的时候在常量池中新建了“abc”。我很想问,这“abc”有在堆内存中存在么。

还有
String a=new String( “abc”);
常量池中的abc和堆内存中的abc有什么关系么。

评分

参与人数 1技术分 +1 收起 理由
lwj123 + 1

查看全部评分

15 个回复

正序浏览
还真没想到这个问题 问的不错
回复 使用道具 举报
本帖最后由 1017161726 于 2015-4-18 12:54 编辑

String a="abc",堆内存中如果有,就直接引用,没有就调用new方法新建一个。String s=new String("abc"),是不管堆内存红有没有,都直接新建一个对象。
可以不用纠结常量池的问题。
回复 使用道具 举报
lwj123 发表于 2015-4-18 11:40
两个位置都不一样,就没什么关系了

谢谢版主啦,不过String的内存机制真的如7楼画的那样么。
堆内存存储的String对象那个“abc”是常量池的引用?

回复 使用道具 举报
两个位置都不一样,就没什么关系了
回复 使用道具 举报
1.当使用String str="abc",这种方式时,先去内存的Heap中找是否存在"abc"这个字符串,若存在,则将地址引用。若不存在则创建。

2.当使用String str=new String("abc");时,不管事先是否存在"abc",每次都会创建其新的对象。
回复 使用道具 举报
我的猜想:要知道键盘上的每个输入按键基本都可以通过那个什么码表转换成数值型数据,所以我想到的是String类在常量池中实现初始化有点类似于查表法(看过毕向东老师的视频的朋友应该有所了解),因此它是可以看作是在常量池中以字符数组为底层直接实现的,不用到堆内存那里去,其实内存真实运作是咋样,谁都不能完全描述,但底层运作基本都是基于硬件高低电平(数字电路表示形式为0,1)差异的叠积达到不同效果的吧:o
回复 使用道具 举报
哎,这个问题,太神奇了
回复 使用道具 举报
D:\0322\第二个春天\day13\code
回复 使用道具 举报
"abc"在方法区中的静态区是单个字符的'a'  'b'  'c'...   你要字符串"abc"他在常量池中创建之前是没有的  所以你就得要创建   创建的时候是把字符'a' 'b' 'c'  拿出来重复的只拿一次完了就开始创建....
回复 使用道具 举报
showdy 中级黑马 2015-4-17 21:04:50
7#
我给你看一张内存看,一目了然

字符串的通过new和直接赋值的区别图解.gif (10.72 KB, 下载次数: 6)

字符串的通过new和直接赋值的区别图解.gif
回复 使用道具 举报
坐等答案啊   求解中
回复 使用道具 举报
lslkkk 来自手机 中级黑马 2015-4-17 20:42:35
报纸
来看大神们解答疑难
回复 使用道具 举报
396460221 发表于 2015-4-17 17:10
我的理解是,常量池中是单个字符的,比如 a b c d或其他特殊字符都是单个的,当有英文字符串时他们会去常量 ...

这方法我也懒得纠结了,网上都没有一个统一的说法。
API的解释是这样的,
String s=“abc”
相当于
char[]  c={'a','b','c'}
String s=new Stinrg(c).

按这样说法“abc”是存储在堆内存中。
但是很多人又说“abc”的引用指向的是常量池。

还有,常量池的话是在方法区的。
回复 使用道具 举报
我的理解是,常量池中是单个字符的,比如 a b c d或其他特殊字符都是单个的,当有英文字符串时他们会去常量池中找相对应的单个字符组成字符串。如果直接写String s = "abc",s的引用只指向常量池中的地址。如果写成String s = new String("abc"),,堆内存中会给s分配地址,并且他指向的也是常量池中的地址。常量池我不知道在哪片内存中,如果理解不对,请见谅。
回复 使用道具 举报
还真没注意到这个问题
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马