java中的字符串到底是在方法区的常量池里还是new出来的对象里?

eg:Stringstr="nihao";看视频教程将内存图时说字符串类在常量池,后来讲String数组时又说会新建一个对象,把我搞晕了..... eg: String str = "nihao";
看视频教程将内存图时说字符串类在常量池,后来讲String数组时又说会新建一个对象,把我搞晕了..
展开
 我来答
dafeiyu
2017-12-29 · 听君歌一曲,琵琶系心弦
dafeiyu
采纳数:75 获赞数:3543

向TA提问 私信TA
展开全部

String实质是字符数组,两个特点:1、该类不可被继承;2、不可变性(immutable)

例如 String s1 = new String("myString");

和 String s1 = "myString"; 

第一种方式通过关键字new定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间,保证常量池中只有一个“myString”常量,节省内存空间。然后在内存堆中开辟一块空间存放new出来的String实例,在栈中开辟一块空间,命名为“s1”,存放的值为堆中String实例的内存地址,这个过程就是将引用s1指向new出来的String实例

第二种方式直接定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址

百度网友324204d
推荐于2017-12-29 · TA获得超过648个赞
知道小有建树答主
回答量:380
采纳率:85%
帮助的人:297万
展开全部

String str ="nihao";

当这段代码编译的时候,首先它会去堆里的方法区常量池里去查找,如果有一个同样的字符串“nihao”,存在,那么它会把当前声明的对象的地址指向那个字符串对象,调用的是String.itern()方法。如果没有的话,它会开启堆内存,分割一块新的地址指向str对象。

String是不可变的(final的),不必担心稳定性问题。

而当你新new一个String数组的时候,当你给String数组赋值的时候,它同样遵循这个原理。

这样做的好处:字符串多重利用,防止产生冗余。

详情参考jdk中String类的的itern方法:

public String intern()

  • 返回字符串对象的规范化表示形式。

    一个初始为空的字符串池,它由类 String 私有地维护。

    当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。

    它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当
    s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

    所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。

本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
惬意又清冽的松柏8224
推荐于2017-12-29 · TA获得超过522个赞
知道小有建树答主
回答量:781
采纳率:90%
帮助的人:520万
展开全部

String str ="nihao";

当这段代码编译的时候,首先它会去堆里的方法区常量池里去查找,如果有一个同样的字符串“nihao”,存在,那么它会把当前声明的对象的地址指向那个字符串对象,调用的是String.itern()方法。如果没有的话,它会开启堆内存,分割一块新的地址指向str对象。

String是不可变的(final的),不必担心稳定性问题。

而当你新new一个String数组的时候,当你给String数组赋值的时候,它同样遵循这个原理。

这样做的好处:字符串多重利用,防止产生冗余。

详情参考jdk中String类的的itern方法:

public String intern()

  • 返回字符串对象的规范化表示形式。

    一个初始为空的字符串池,它由类 String 私有地维护。

    当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。

    它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

    所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。

本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
puziguo
2017-12-29 · TA获得超过1928个赞
知道小有建树答主
回答量:884
采纳率:86%
帮助的人:811万
展开全部

String str = "nihao";  程序开始执行这句代码,肯定是要创建一个对象的, 只是这个对象创建后就是一个常量,不可以更改, 并且这个对象是放在串池里面的,也就是你说的那个常量池

如果我后面在写一句代码:  String other = "nihao";

str和other这2个引用的地址就是一样的,  因为str和other的声明方式是一样的, 都是在串池, str的对象创建时,串池中没有"nihao"这个常量,就创建一个. other对象创建时,发现串池中已经有了"nihao"这个常量, 就直接拿过来用就是了

String a1 = new String("nihao");
String b1 = new String("nihao");

但是如果我们通过上面的方式直接new String()  那个a1和b1这2个引用的对象就不是在串池中了,而是在堆中, 但是new String() 的参数"nihao"也是一个字符串啊, 这个字符串从哪里来呢?如果我们吧代码拆分一下就明白了:

String para = "nihao";
String a1 = new String(para);

就会发现String a1 = new String("nihao"); 这一句代码实际上创建了2个对象, 一个是String对象,存放在堆中, 一个是字符串常量对象,存放在串池中

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
abcd6559402
2017-12-29 · TA获得超过2054个赞
知道小有建树答主
回答量:1883
采纳率:62%
帮助的人:207万
展开全部
在最开始时,没有东西时会新建对象。如 String str = "Hello,Welcome to java world"会创建一个新对象并将此值放在常量池中。当你在创建变量String str2 = "Hello,Welcome to java world"时str2这个引用变量会指向str创建的对象,不会新创建对象。但是如果你用new的话会创建新对象。如String str3 = new String("Hello,Welcome to java world");则会使用已经有的str指向的对象来创建一个新对象。因此,在使用new String()时要注意有两个对象出现。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(8)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式